はじめに
Vue.jsのコンポーネントはそれぞれが独立していますがスタイルブロックに記述したCSSはコンポーネントごとに独立していないので他のコンポーネントの影響を受けてしまいます。そのためみなさんscoped CSSでCSSの適応範囲をコンポーネント内にのみ適用するよう実装することでコンポーネント間のスタイルの干渉を防いでいるのではないでしょうか?
しかし、例外的に親コンポーネントから子コンポーネントのスタイルを上書きしたい場合があるかもしれません。そんな時に使えるのがdeepセレクターというです。これを使うと、例外的に親から子のスタイルを上書きできるようになります。それでは、さっそく使い方を見ていきましょう。
deepセレクターの使い方
<script setup>
import Child from "@/Child.vue";
</script>
<template>
<div class="parent">
<h2>親コンポーネント</h2>
<Child />
</div>
</template>
<style scoped>
.parent {
font-family: Arial, sans-serif;
}
.child {
color: red;
font-weight: bold;
}
</style>
<template>
<div><p class="child">子コンポーネントのテキスト</p></div>
</template>
<style scoped>
.child {
color: green;
font-size: 16px;
}
</style>
上記の例では、App.vueからChild.vueのコンポーネントを呼び出しています。Child.vueの「子コンポーネントのテキスト」というpタグにはchildクラスを設定しており、Child.vueでは.childクラスにcolor:green、App.vueでは.childクラスにcolor:redを設定してみました。実行画面を確認するとテキストカラーはgreenが適用されていると思います。これは、Child.vueでscoped CSSを使っておりコンポーネント外からのスタイル指定の影響を受けないためApp.vueのスタイル指定を無視してgreenが適用されています。
では、このスタイルを上書きするためにdeepセレクターを使ってみましょう。
App.vueのスタイルを以下のように書き換えてください。実行画面を確認するとテキストカラーが上書きされたと思います。スタイルを上書きするには擬似クラス:deep()を上書きしたいクラスに使用することで例外的に子コンポーネントのスタイルを親コンポーネントから上書きできます。
:deep(.child) {
color: red;
font-weight: bold;
}
まとめ
いかがでしたでしょうか?今回は親コンポーネントから子コンポーネントのスタイルを上書きする方法を紹介しました。 deepセレクターはスタイルのカプセル化を破ることができる強力な機能ですがカプセル化という本来の設計を無視するものなので可能な限り避けるべき機能です。第一に考えるべきは再利用性と保守性のある実装ですのでCSSの!import同様極力使わずにやむを得ない場合のみ使用するようにしましょう。