🐊

Vueで 動的に生成されるコンテンツにスタイルを当てる

2020/10/18に公開

問題

Vueで動的に生成されるコンテンツにスタイルが効かない

フォームの送信画面で 動的に生成されるコンテンツのエラーメッセージ の色と位置の微調整をしたいときにハマったので備忘録と記憶の定着のためにアウトプットしていきます。
(送信を押さないとその要素はDOM上に存在しない v-html によって作成された DOM コンテンツ)

結論 ::v-deepで解決

ディープセレクタ
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html

sample.vue
<template>

 <span>名前(必須)</span>
 <input class="DOM上に元から存在するクラス">
 <span>お取り寄せ内容(必須)</span>
 <input class="DOM上に元から存在するクラス">
  <!-- inputが空の場合DOM上に.q-bottom-errorが動的に追加される -->
  <span class="q-bottom-error">お取り寄せ内容を入力してください</span>

</template>

<style lang="scss" scoped> 
/* 例 inputタグが空の時に出るエラーメッセージの色を青にしたい */
 .DOM上に元から存在するクラス ::deep .動的に生成されるコンテンツのクラス(.q-bottom-error) {
   color: blue;
 }
</style>

Scoped CSSとは

Vue.jsでCSSを利用する際にScoped CSSやCSS Modules、CSS-in-JSなどの手法がある。
Scoped CSSとはある特定の範囲にのみCSSを適用できる機能
scoped 属性をもつ <style> タグを利用するとき、その CSS は現在のコンポーネントの要素にのみ適用される。

sample.vue
<template>
 <div class="hage">フサフサ</div>
</template>

<style scoped>
/* sample.vueのhageクラスのみに適用されるcss他ファイルには適用されない */
 .hage {
   color: red;
 }
</style>

なぜこのファイルにしか効かないようになるのか

<style scoped>にすることによって
Vue.jsでは、HTML側にコンポーネント毎にカスタムデータ属性を付与し、CSS側にも対応するデータ属性を付与する。

sample1.vue
<template>
 <div class="hage" [data-v-f3f3eg9]>ふさふさ</div>
</template>

<style scoped>
 .hage[data-v-f3f3eg9] {
   color:red
 }
</style>

となるので

sample2.vue
<template>
<!-- こちらのhageは赤にならない -->
 <div class="hage">ふさふさ</div>
</template>

参考にしたページ

Scoped CSSにおけるCSS設計手法
https://ics.media/entry/200515/
スコープ付き CSS
https://vue-loader-v14.vuejs.org/ja/features/scoped-css.html
ZennのMarkdown記法
https://zenn.dev/zenn/articles/markdown-guide

Discussion