Scoped CSS の例外的挙動について
TweetScoped CSS は、子コンポーネントに効いてしまう場合がある
Scoped CSS の特徴は、それが書かれたコンポーネントにしかスタイリングが効かないことでした。 これにより保守性の高い CSS を書くことができました。
しかし、Scoped CSS で書いたスタイリングが、そのコンポーネント外、具体的には子コンポーネントに効いてしまう場合があります。これについて解説します。
Scoped CSS は、子コンポーネントの一番上の要素には効いてしまう
まず親のコンポーネント App.vue が次のようになっていたとします。
App.vue で scoped CSS を使う
<template>
<div class="wrapper">App.vue <First /></div>
</template>
<script>
import First from "./components/First";
export default {
name: "App",
components: {
First
}
};
</script>
<style scoped>
.wrapper {
border: 1px solid blue;
}
</style>
そして App.vue の子コンポーネントである First.vue が次のようになっていたとしましょう。 すると、本来は App.vue のスタイリングは First.vue には効かないことを普通を想定するわけですが、実際には効いてしまいます。
First.vue の .wrapper にも効いてしまう
<template>
<!--
App.vue の Scoped CSS は、
子要素の一番上の要素にまでは効いてしまう
-->
<div class="wrapper"><h2>First</h2></div>
</template>
<script></script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>
何故ならば、親コンポーネントの Scoped CSS は、子コンポーネントの一番上の要素にも効いてしまうからです。
解決策
親コンポーネントの Scoped CSS は、子コンポーネントの一番上の要素にも効いてしまうので、その解決策の一つとしては、子コンポーネントの一番上の階層に div を置いてしまう手法があります。
こうすれば First.vue の .wrapper には効かない
<template>
<!--
一枚 div が挟まれているので、
App.vue の Scoped CSS を効かないようにできている
-->
<div>
<div class="wrapper"><h2>First</h2></div>
</div>
</template>
<script></script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped></style>