https://medium.com/vuejs-tips/override-scoped-css-de4275119b87
単一ファイルコンポーネントを作る時、
style scoped として CSSの影響範囲をコンポーネント内に収めるわけですが、
コンポーネント外部から内部のスタイルを変更したい場合があります。
<template>
<div class="box">
<div class="message">
<slot></slot>
</div>
</div>
</template>
<script>
export default {
name: 'box'
}
</script>
<style scoped>
.box {
display: inline-block;
}
.box .message {
background-color: orange;
padding: 1em;
}
</style>
前提として、Boxコンポーネントは登録済みです。
import Vue from 'vue'
import App from './App.vue'
import Box from './Box.vue'
Vue.component('box', Box)
new Vue({
el: '#app',
render: h => h(App)
})
次のようなテンプレートを記述したとします。
<template>
<div id="app">
<box class="green">.green</box>
<box class="green override">.green.override</box>
<span class="parent"><box class="green">.parent .green</box></span>
</div>
</template>
<script>
export default {
name: 'app',
data () {
return {
}
}
}
</script>
<style scoped>
</style>
この時の表示は以下のようになります。
ここで、ボックスの色をオレンジから緑に変えたいとします。
この時のHTML(1つめのボックス部分)はこのようになっています。
単純に1つめのボックスに対してCSSを記述してみます。
<style scoped>
.green .message {
background-color: green;
}
/* or */
.box .message {
background-color: green;
}
</style>
まとめて2つ書きましたが、scopedされているため、このどちらも作用しません。
次のように属性セレクタをつけることで作用させることができますが、
セレクタに用いる属性値を事前に知ることはできません。
.green .message[data-v-1461803c] {
background-color: green;
}
/* or */
.box[data-v-1461803c] .message[data-v-1461803c] {
background-color: green;
}
scoped スタイルで入れ子のセレクタが必要なら、CSS に対して >>> オペレータを使用する必要があります。
https://vue-loader.vuejs.org/ja/features/scoped-css.html
と引用元に記載されているのを参考に次のようにしてみますが、やはり効果がありません。
.green >>> .message {
background-color: green;
}
どうやらセレクタは期待通りに動作しているようです。
しかし、CSSの適用順によってうまく効果が出ていないことがわかります。
どちらも詳細度が同じ為、順序が優先されています。
https://specificity.keegan.st/
1つ目のボックスのようにクラス1つでは詳細度が足りないため、2つ目のボックスのようにクラスを2つ付けます。
<box class="green override">.green.override</box>
これに対して、次のようにCSSを記述することで詳細度を上げ、指定を優先させることができます。
.green.override >>> .message {
background-color: green;
}
または、3つ目のボックスのように親要素をつけることでも実現できます。
<span class="parent"><box class="green">.parent .green</box></span>
.parent .green >>> .message {
background-color: green;
}
これで、望みどおりのスタイルが適用できました。