LoginSignup
78
73

More than 3 years have passed since last update.

ElementUI に Scoped CSS が適用されない問題対応策

Last updated at Posted at 2017-12-26

宮崎在住エンジニアのジョウ(@JotarO_Oyanagi) です。

Vue.js 用 UI ライブラリ Element の要素に対し、Scoped CSS を使う場合に起きうる問題(後述)への対応策を紹介します。

TL;DR

  • Element の要素に Scoped CSS のスタイルが適用されないケースがある。
  • 原因は、通常の記述方法だとセレクタの子要素に data 属性がつき、そこに対してスタイルがあたるが、Element が書き出す一部の要素には data 属性がつかない。
  • 対応策としては /deep/ セレクタを使用する。

Scoped CSS とは

コンポーネントごとの CSS を書ける仕組みです。

<style scoped> とすると、そこに記述されたセレクタに対し、ユニークな data 属性がつき、その data 属性がセレクタに付加されます。

具体的にはどういうことか、公式の記述を抜粋してご紹介します。

参考:スコープ付き CSS

<style scoped>
.example {
  color: red;
}
</style>

<template>
  <div class="example">hi</div>
</template>

と記述すると、以下の状態で書き出されます。

<style>
.example[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example" data-v-f3f3eg9>hi</div>
</template>

data-v-f3f3eg9 という属性が付加されましたね。

セレクタに子要素を記述した場合には以下のようになります。

<style scoped>
.example .child {
  color: red;
}
</style>

<template>
  <div class="example">
    <span class="child">hi</span>
  </div>
</template>

この場合、以下の状態で書き出されます。

<style>
.example .child[data-v-f3f3eg9] {
  color: red;
}
</style>

<template>
  <div class="example">
    <span class="child" data-v-f3f3eg9>hi</span>
  </div>
</template>

親ではなく子の要素に data 属性がつきます。

Element が書き出す一部の要素には data 属性がつかない

以下の記述で書き出されたソースをご覧ください。

<style lang="sass" scoped>
.RootApp

  .el-input
    display: block
    margin: 10px auto
    width: 90%

    &__inner
      border-radius: 0
</style>

<template>
  <div class="RootApp">
    <el-input/>
  </div>
</template>

この場合、以下の状態で書き出されます。

スクリーンショット 2017-12-26 19.11.31.png

<el-input> により .el-input.el-input__inner が書き出されています。

.el-input には data 属性がついているのでスタイルが適用されていますが、

スクリーンショット 2017-12-26 19.14.08.png

.el-input__inner には data 属性がないため、スタイルが適用されません。

これを解決するためにどうすればいいかと小一時間調べてみると、公式にその答えが書いてありました。
上で散々挙げたスコープ付き CSSの一番下に書いてあります。

Vue の公式はマジで優秀。

親要素に data 属性をつけるには、/deep/ セレクタを使う

vue-loader v12.2.0 以上 ならば、/deep/ セレクタという仕組みがあるとのことで、それを使うと data 属性が親要素につきます。

Sass ならこう書くと

<style lang="sass" scoped>
- .RootApp
+ .RootApp /deep/

  .el-input
    display: block
    margin: 10px auto
    width: 90%

    &__inner
      border-radius: 0
</style>

こうなります。

スクリーンショット 2017-12-26 19.27.38.png

セレクタの親要素に data 属性がついて、無事 .el-input__inner にスタイルが適用されました!

Sass ではなく、通常の CSS の書き方なら >>> を使います。

<style scoped>
.RootApp >>> .el-input__inner {
  border-radius: 0
}
</style>

おわりに

Vue 関連は「公式読め」で解決することがホント多い。

参考資料

78
73
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
78
73