宮崎在住エンジニアのジョウ(@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>
この場合、以下の状態で書き出されます。
<el-input>
により .el-input
と .el-input__inner
が書き出されています。
.el-input
には data 属性がついているのでスタイルが適用されていますが、
.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>
こうなります。
セレクタの親要素に data 属性がついて、無事 .el-input__inner
にスタイルが適用されました!
Sass ではなく、通常の CSS の書き方なら >>>
を使います。
<style scoped>
.RootApp >>> .el-input__inner {
border-radius: 0
}
</style>
おわりに
Vue 関連は「公式読め」で解決することがホント多い。