🐈
【Vue3.0】Scoped CSSが改善された話
更新内容
ScopedCSSの改善
以下のissueで議論されている下記の問題がこの更新で改善されました。
詳細はコメント欄にて記載して議論しています。
scoped によって、親コンポーネントのスタイルは子コンポーネントに漏れません。ただし、子コンポーネントのルートノードは親スコープの CSS と子スコープの CSS と両方によって影響を受けます。これは、設計上、親はレイアウトが目的で子のルート要素をスタイルすることができます。
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html
以下議論の通りで、対応はされておらず当該issueのclose自体が不適切の可能性があるため訂正しました。
https://zenn.dev/karan_coron/articles/87597250de406018e351#comment-ed3a4a32ad03e3351752
上記、対応されているとの報告があったため、一旦保留にします。
v-slot, ::v-deep, scopedのスタイリング記述方法の改善
ScopedCSSの記述方法が改善されます。
ディープセレクタの記述方法は従来、以下の記述でしたが、
<style>
.a ::v-deep b ...
.a >>> b ...
.a /deep/ b ...
</style>
または、
<style scoped>
.a ::v-deep b ...
.a >>> b ...
.a /deep/ b ...
</style>
以下のような記述ができて、v-slot
, ::v-deep
, scoped
の記述がより直感的にスタイリングできるようになりました。
<style> <!-- global -->
/* deep selectors */
.a ::v-deep(.b) ...
/* slot */
.a ::v-slotted(.b) ...
/* global */
.a ::v-global(.b) ...
</style>
<style scoped> <!-- scoped -->
</style>
<style deep> <!-- ::v-deep -->
</style>
<style slotted> <!-- ::v-slotted -->
</style>
おわりに
何か間違えや質問などあればコメントお願いします。
Discussion
「ScopedCSSの改善」の箇所ですが、RFC を読んでも解決してない気がしたので Vue 3 系で試してみましたが、特に仕様は変わっていないように思えました。
私も以前から気になっていた箇所なので、この仕様に関してはどうにかならないかと思っていたところではあります。
この件ですが、長らくVue2で議論されていた上記問題のissueが当該のPRでcloseされて、この問題は解決したと書かれていたため、対応されたものだと思っておりました。
こちらでも調べてみたところ対応されていないのにPRがcloseされているようでした…。
こちら適用されているという情報もあるため、一旦元に戻します。
一応ですが、私の環境ですと Vue CLI を使用してプロジェクトを新規作成し、以下のバージョンになっていました。
確認方法としては
src/App.vue
の style を以下に変更して、HelloWorld コンポーネントの背景色が変わるのを確認できました。クラス名で指定した場合はどうでしょうか?問題となっていたのは子コンポーネントで定義されたクラス名と親コンポーネントで定義されたクラス名のバッティングについてです。
ブロック要素そのものに、スタイルが当たるのは仕方ないかと思います。
それも試しましたが同じく背景色が HelloWorld コンポーネントに反映されいるようです。
src/App.vue
を以下に設定。src/components/HelloWorld.vue
を以下に設定。と変更をして確認をしてみました。
こちらですと、現状の以下の仕様と違っているように思えましたので、もしかしたらですが認識そのものが違っている可能性もあるかなとも思いました。
子コンポーネントのスタイルを同じ名前で当てても親が優先されるのですか?それですと、認識が違うかもしれません。
追記
親コンポーネントで定義したクラス名に当てたスタイルと子コンポーネントで定義したクラス名に当てたスタイルで、親からの影響を受け、上書きされてしまう場合の話です。
試しに両方に設定してみました。
src/App.vue
を以下に設定。src/components/HelloWorld.vue
を以下に設定。すると両方がマージされた上で、同じプロパティは親コンポーネントの記述が優先されました。
ただ、お話はその点ではなくて「子コンポーネントのルートノード」が「親スコープの CSS と子スコープの CSS と両方」によって影響を受けることに違いないかなと思いまして。
issue の問題が解決されているかは、私の英語力が足りず判断はつかないのですが、引用されている仕様については変わっていなように思えましたので。
こちらでも試しました。
App.vue
CoverStyled.vue
以下でハッシュ値が変わっていましたのでクラスの上書きはされていませんでしたね。
これ自体は今回の改修の(issue の問題が解決されている)旨であっていると思います。
html
css
ただ、おっしゃるっとおり、
スタイルの上書きはされそうです。
issue の内容はセレクタが同じ(スコープ)になる問題だったということですね。
理解できました。ありがとうございます。
ということは、issue については解決したが、引用されている仕様については変更はないということですね。