LoginSignup
0
0

More than 3 years have passed since last update.

【Vue CLI】<style scoped>で子コンポーネントのスタイルがどう変わるか検証した

Last updated at Posted at 2020-05-30

結論

<style scoped>で子コンポーネントスタイルを設定したら、そのスタイルは子コンポーネントの一番上のルートにだけ適応される

というルールを検証した結果、その通りだった。

参考:
vue-loader -子コンポーネントのルート要素-
vue-loaderのScoped CSSのスタイルが子コンポーネントのルート要素に効いてしまって辛い

Vue CLIを触り初めて1週間、コンポーネントの<style>の書き方が間違っていて、思い通りのレイアウトにならず苦労した。
後日また同じことで悩まないように、やった手順とよくなかった点をメモしておく。
そしてこの記事が誰かのためになれると嬉しい。

検証画面の構成

コンポーネントの構成

image.png

作成したファイル


- src
    - components
        - ContinueButton.vue
    - views
        - Pj002.vue

ソース

↓コンテニューボタンの単一コンポーネント

ContinueButton.vue

<template>
  <div class="continue-container">
    <p>
      CONTINUE
      <span class="continue-text">
        >
      </span>
    </p>
  </div>
</template>


↓メインページ *コンテニューボタンのスタイルはすべてココに書いている

Pj002.vue
<template>
  <div class="background">
    <main>
      <ContinueButton></ContinueButton>
    </main>
  </div>
</template>

<script>
import ContinueButton from '@/components/ContinueButton.vue';

export default {
  name: 'Pj002',
  components: {
    ContinueButton,
  },
};
</script>

<style>
@import url('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: 5px solid #ffffff;
  text-align: center;
  line-height: 45px;
  opacity: 1;
}

/* コンテニューボタンの文字フォントなどを設定 */
.continue-container p {
  position: absolute;
  width: 100%;
  top: 20%;
  left: 60%;
  transform: translate(-50%, -50%);
  letter-spacing: 1.6px;
  color: #ffffff;
  font: 48px/32px Bebas Neue;
  opacity: 1;
}

/* コンテニューボタンの"CONTINUE"と">"の間の余白を設定 */
.continue-text {
  text-align: left;
  margin-left: 80px;
}
</style>


<style>を変えたらどうなるか

<style>のままの場合

見た目

理想通り。
スタイルがscopedになっていないので、CSSはグローバルで定義されていることになり、コンテニューボタンのレイアウトも問題なく表示される。
image.png

<style scoped>にした場合

見た目

image.png

変わったところ、変わらなかったところ

  1. 白いボーダーラインは何も変わらずきちんと表示されている
  2. 文字のフォントが変わっている
  3. "CONTINUE" と ">" の間の余白がなくなっている

<template>のclass属性も上記の順番で設定している。
image.png

冒頭の結論で出した通り、やはり子コンポーネントの1番上の要素は<style scoped>にしたにも関わらずレイアウトが適応されている。
それ以下のスタイルは適応されていない。

ちなみに<style module>にした場合

見た目

image.png

変わったところ、変わらなかったところ

子コンポーネントのスタイルは一番上の要素であっても適応されない。 ・・・!!?
(※"CONTINUE >"という文字列も表示されなくなった点については理由がわかっていないので、どなたかわかる方がいれば教えていただきたいです。)

ソース

class属性の記載方法がv-bindに変わるのでソースを載せておく。

ContinueButton.vue

<template>
  <div :class="$style.continue_container">
    <p>
      CONTINUE
      <span :class="$style.continue_text">
        >
      </span>
    </p>
  </div>
</template>

Pj002.vue

<template>
  <div :class="$style.background">
    <main>
      <ContinueButton></ContinueButton>
    </main>
  </div>
</template>

<script>
import ContinueButton from '@/components/ContinueButton.vue';

export default {
  name: 'Pj002',
  components: {
    ContinueButton,
  },
};
</script>

<style module>
/* Pj002.vue全体の背景 */
@import url('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: 5px solid #ffffff;
  text-align: center;
  line-height: 45px;
  opacity: 1;
}

/* コンテニューボタンの文字フォントなどを設定 */
.continue_container p {
  position: absolute;
  width: 100%;
  top: 20%;
  left: 60%;
  transform: translate(-50%, -50%);
  letter-spacing: 1.6px;
  color: #ffffff;
  font: 48px/32px Bebas Neue;
  opacity: 1;
}

/* コンテニューボタンの"CONTINUE"と">"の間の余白を設定 */
.continue_text {
  text-align: left;
  margin-left: 80px;
}
</style>


開発者ツールでの確認結果

<!-- --> になっている
image.png

まとめ

<style scoped>にしても、子コンポーネントの一番上のルートにはスタイルが適応されてしまうので注意すべき。
一部だけ反映されるから「CSSどっかいじってしまったかな?」なんて微調整し始めると沼。
公式のスタイルガイドにて、<style scoped>の使用は必須レベルで推奨されているので、きちんと使いこなせるようになりたい。

参考:
スタイルガイド -コンポーネントスタイルのスコープ-
【Vue.js】Scoped CSSよりCSS Modulesの方がベターだった件

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0