0%

Programmingプログラミングナレッジ

Posted:2019.05.29

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

Vue.jsではそれぞれの要素をコンポーネントと定義し、それらを組み合わせる形でプロジェクトが構成されているケースが多いです。そして、単一コンポーネントファイル(過去記事「Vueインスタンスで使うオプションと単一ファイルコンポーネントについて(単一ファイルコンポーネント編) 」参考)では、1つのファイルでHTMLとjavascript、CSSをまとめて記述していきます。

 

この時にコンポーネント内の要素に対してはCSSを適用できますが、呼び出している子コンポーネントにある要素へはそのままですとスタイルが適用されません。今回は「ディープセレクタ」を使って、親コンポーネントから子コンポーネントの要素に対してスタイルを適用させる方法をまとめていきます。

 

まず、一般的な親子構造のコンポーネントで、スタイルを適用させる例を見ていきます。親コンポーネント側で特定の要素に対してスタイルを指定します。そして子コンポーネント側でも同じスタイルを適用させたい要素を用意します。

ComponentParent.vue】

<template>
 <div class="parent">
  <p class="text">親コンポーネントの要素</p>
  <component-children />
 </div>
</template>

<script>
 import ComponentChildren from '../components/ComponentChildren.vue'
 export default {
  name: 'ComponentParent',
  components: {
   ComponentChildren
  }
 }
</script>

<style scoped lang="scss">
 p {
  color: red;
 }
</style>

 

ComponentChildren.vue】

<template>
 <div class="children">
  <p class="text">子コンポーネントの要素</p>
 </div>
</template>

<script>
 export default {
  name: 'ComponentChildren'
 }
</script>

 

ビルドして確認してみますと、このように親コンポーネントの要素にはスタイルが適用されているのが確認できますが、子コンポーネントには同じセレクタで指定しているもののスタイルが適用されていません。

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

 

これはVueコンポーネントのstyle要素にscoped属性が適用されているのが理由です。つまり、通常ではコンポーネント内でしかスタイルが適用されないようになっています。

<style scoped>
 // コンポーネント内のみ適用されるスタイル
</style>

 

とりわけVue.jsでは、ビルド後にはコンポーネントごとに独自のdata属性が自動的に割り振られます。実際には下記のような形になります。

【HTML】※一部抜粋

<div class="parent" data-v-452d6c4c="">
 <p class="text" data-v-452d6c4c="">親コンポーネントの要素</p>
 <div class="children" data-v-452d6c4c="">
  <p class="text">子コンポーネントの要素</p>
 </div>
</div>

 

そこで、「ディープセレクタ」というものを使うことで、子コンポーネントの要素にもセレクタで指定できるようにしていきます。具体的には下記のように「>>>」もしくは「/deep/」という記述を追加します。

【Parent.vue】※一部抜粋

<style scoped lang="sass">
 >>> .text {
  color: red;
 }
</style>

....もしくは

<style scoped lang="scss">
 /deep/ .text {
  color: red;
 }
</style>

 

2通りありますが、SCSS記法の場合ですと「>>>」の記述が読み込まれないようですので、この場合は「/deep/」の方を選択するようにします。これで実際にブラウザで確認してみますと子コンポーネントにもスタイルが適用されているのが確認できます。

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

 

ビルド後はどのような形でCSSが適用されているかを、ディープセレクタ適用前と比較してみるとよくわかりますね。

【CSS】※一部抜粋

// ディープセレクタ適用前
.text[data-v-452d6c4c] {
 color: red;
}

// ディープセレクタ適用後
[data-v-452d6c4c] .text {
 color: red;
}

 

 

v-htmlのディレクティブで出力された要素にスタイルを適用する

先ほどは親コンポーネントから子コンポーネントへの適用でした。また、Vue.jsのディレクティブで、HTMLをそのまま出力できる「v-html」というものがあります。これは指定した要素の子要素に、対象のHTML文字列をそのまま出力できるものになります。

 

このv-htmlのディレクティブを使った時も実質的には親コンポーネントと子コンポーネントのような構成になるので、そのままですと下記のようにスタイルが適用されません。

【Vue】

<template>
 <div id="app">
  <div v-html="content"></div>
 </div>
</template>

<script>
 export default {
  data: function() {
   return {
    content: '<p class="text">v-htmlのディレクティブで出力された要素</p>'
   }
  }
 }
</script>

<style scoped lang="scss">
 .text {
  color: red;
 }
</style>

 

ブラウザで確認してもv-htmlで出力した要素にはスタイルが適用されていません。そこで先ほどと同じくディープセレクタを利用してスタイルを指定します。

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

【Vue】

<template>
 <div id="app">
  <div v-html="content"></div>
 </div>
</template>

<script>
 export default {
  data: function() {
   return {
    content: '<p class="text">v-htmlのディレクティブで出力された要素</p>'
   }
  }
 }
</script>

<style scoped lang="scss">
 /deep/ .text {
  color: red;
 }
</style>

 

これで出力されたHTMLの要素にもスタイルを適用させることができました。

ディープセレクタで子コンポーネントの要素に親コンポーネントのスタイルを適用させる

 


 

いかがでしょうか、Vue.jsの場合はたくさんのコンポーネントを使用するケースが多いかと思いますが、その分複雑になり、スタイルの適用や継承なども考慮しないと思わぬ修正コストが発生してしまいます。そんな時にはこのディープセレクタを使うことで、より効率的かつシンプルにスタイルを管理できるのではないでしょうか。

 

(参考にさせて頂いたサイト)
スコープ付き CSS

author
この記事を書いた人オガワ シンヤ
FacebookTwitter

DesignSupply.代表 / ディレクター・ウェブデザイナー・フロントエンドエンジニアをやっています。「ウェブとデザインでヒト・モノ・サービスを繋げ新しい価値を生み出す」をコンセプトに日々奮闘中!制作中はチョコレートが欠かせない三十路Webクリエイター。

制作のご依頼やお問い合わせ・パートナー業務提携のご相談はこちら

デザインやウェブ制作についてのご依頼やご相談、その他お問い合わせなどもお気軽にご連絡ください。フットワークの軽さやレスポンスの早さ、また豊富な経験や知識、技術を活かした対応力といったフリーランスクリエイターの強みでクライアント様、パートナー企業様のお力になります。デザインからコーディングやWordPress実装といったウェブサイト構築はもちろん、写真撮影や動画編集、コンテンツ制作からサイト運用サポートまで一括してお任せください。

ホームページ制作のご検討やウェブ運用でお悩みの経営者様や企業のウェブ担当者様をはじめ、個人で店舗を営んでいらっしゃるオーナー様、フリーで活動されているビジネスオーナー様はもちろんのこと、リソース不足でお困りの制作会社様、またクリエイターをお探しの代理店様も大歓迎です。

コンタクトをご希望の方はお手数ですが、下記よりお問い合わせフォームのページへアクセスしていただき、必要事項を入力の上メッセージを送信してください。確認でき次第すぐに折り返しご連絡致します。

こんな記事も読まれています

コメントもお気軽にどうぞ

記事に関するご質問やご意見などありましたら下記のコメントフォームよりお気軽に投稿ください。なおメールアドレスは公開されませんのでご安心ください。また、* が付いている欄は必須項目となります。

内容に問題なければ、下記の「コメントを送信する」ボタンを押してください。

CAPTCHA


ページトップへ