結論
<style scoped>
で子コンポーネントスタイルを設定したら、そのスタイルは子コンポーネントの一番上のルートにだけ適応される
というルールを検証した結果、その通りだった。
参考:
vue-loader -子コンポーネントのルート要素-
vue-loaderのScoped CSSのスタイルが子コンポーネントのルート要素に効いてしまって辛い
Vue CLIを触り初めて1週間、コンポーネントの<style>
の書き方が間違っていて、思い通りのレイアウトにならず苦労した。
後日また同じことで悩まないように、やった手順とよくなかった点をメモしておく。
そしてこの記事が誰かのためになれると嬉しい。
検証画面の構成
コンポーネントの構成
作成したファイル
- src
- components
- ContinueButton.vue
- views
- Pj002.vue
ソース
↓コンテニューボタンの単一コンポーネント
<template><divclass="continue-container"><p>
CONTINUE
<spanclass="continue-text">>
</span></p></div></template>
↓メインページ *コンテニューボタンのスタイルはすべてココに書いている
<template><divclass="background"><main><ContinueButton></ContinueButton></main></div></template><script>importContinueButtonfrom'@/components/ContinueButton.vue';exportdefault{name:'Pj002',components:{ContinueButton,},};</script><style>@importurl('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');/* Pj002.vue全体の背景 */.background{height:90%;position:absolute;top:10%;right:0;bottom:0;left:0;background-color:lightblue;}/* コンテニューボタンの白いボーダーラインなどを設定 */.continue-container{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:500px;height:150px;border:5pxsolid#ffffff;text-align:center;line-height:45px;opacity:1;}/* コンテニューボタンの文字フォントなどを設定 */.continue-containerp{position:absolute;width:100%;top:20%;left:60%;transform:translate(-50%,-50%);letter-spacing:1.6px;color:#ffffff;font:48px/32pxBebasNeue;opacity:1;}/* コンテニューボタンの"CONTINUE"と">"の間の余白を設定 */.continue-text{text-align:left;margin-left:80px;}</style>
<style>
を変えたらどうなるか
<style>
のままの場合
見た目
理想通り。
スタイルがscopedになっていないので、CSSはグローバルで定義されていることになり、コンテニューボタンのレイアウトも問題なく表示される。
<style scoped>
にした場合
見た目
変わったところ、変わらなかったところ
- 白いボーダーラインは何も変わらずきちんと表示されている
- 文字のフォントが変わっている
- "CONTINUE" と ">" の間の余白がなくなっている
<template>
のclass属性も上記の順番で設定している。
冒頭の結論で出した通り、やはり子コンポーネントの1番上の要素は<style scoped>
にしたにも関わらずレイアウトが適応されている。
それ以下のスタイルは適応されていない。
ちなみに<style module>
にした場合
見た目
変わったところ、変わらなかったところ
子コンポーネントのスタイルは一番上の要素であっても適応されない。 ・・・!!?
(※"CONTINUE >"という文字列も表示されなくなった点については理由がわかっていないので、どなたかわかる方がいれば教えていただきたいです。)
ソース
class属性の記載方法がv-bind
に変わるのでソースを載せておく。
<template><div:class="$style.continue_container"><p>
CONTINUE
<span:class="$style.continue_text">>
</span></p></div></template>
<template><div:class="$style.background"><main><ContinueButton></ContinueButton></main></div></template><script>importContinueButtonfrom'@/components/ContinueButton.vue';exportdefault{name:'Pj002',components:{ContinueButton,},};</script><stylemodule>/* Pj002.vue全体の背景 */@importurl('https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap');.background{height:90%;position:absolute;top:10%;right:0;bottom:0;left:0;background-color:lightblue;}/* コンテニューボタンの白いボーダーラインなどを設定 */.continue_container{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:500px;height:150px;border:5pxsolid#ffffff;text-align:center;line-height:45px;opacity:1;}/* コンテニューボタンの文字フォントなどを設定 */.continue_containerp{position:absolute;width:100%;top:20%;left:60%;transform:translate(-50%,-50%);letter-spacing:1.6px;color:#ffffff;font:48px/32pxBebasNeue;opacity:1;}/* コンテニューボタンの"CONTINUE"と">"の間の余白を設定 */.continue_text{text-align:left;margin-left:80px;}</style>
開発者ツールでの確認結果
まとめ
<style scoped>
にしても、子コンポーネントの一番上のルートにはスタイルが適応されてしまうので注意すべき。
一部だけ反映されるから「CSSどっかいじってしまったかな?」なんて微調整し始めると沼。
公式のスタイルガイドにて、<style scoped>
の使用は必須レベルで推奨されているので、きちんと使いこなせるようになりたい。
参考:
スタイルガイド -コンポーネントスタイルのスコープ-
【Vue.js】Scoped CSSよりCSS Modulesの方がベターだった件