LoginSignup
2
0

Vue.js グローバルな css と併用する場合、コンポーネントは CSS Modules を利用するのがよさそう

Last updated at Posted at 2023-12-04
  • 現在: 汎用&コンポーネントなセレクタ含めて、グローバルな css ファイルに定義されている
  • 将来: コンポーネント用のセレクタはコンポーネントに移動しつつ、汎用的なセレクタは Tailwind 等を利用 -> purge させたい

という状況で、コンポーネントは Scoped CSS or CSS Modules どちらが良さそうか調べたときのメモ。

結論

  • Scoped CSS だとグローバルな css で定義されたセレクタが適用される場合がある
    • グローバルな cssを変更すると、Scoped CSS で定義したコンポーネントに影響ある可能性あり
  • 前述の理由から、コンポーネントでは CSS Modules を利用した方がよさそう
  • 参考: 【Vue.js】Scoped CSSよりCSS Modulesの方がベターだった件

デモ・検証

デモは Nuxt3 を使用しているが、Scoped CSS, CSS Modules の仕組みは Vue.js と同じ。

npm run build -> _nuxt/dist/client/_nuxt/entry.[hash].css を見てみると、次のようにビルドされる。

/* ScopedCssComponent.vue */
.flex[data-v-af7180a1] {
  align-items: center;
  display: flex;
  font-size: 16px;
  justify-content: center;
}
.flex span[data-v-af7180a1] {
  font-size: 12px;
}
.flex .label[data-v-af7180a1] {
  font-size: 14px;
}
.flex .underline[data-v-af7180a1] {
  text-decoration-line: unset;
}

/* CSSModuleComponent.vue */
._flex_z1ykh_1 {
  align-items: center;
  display: flex;
  font-size: 16px;
  justify-content: center;
}
._flex_z1ykh_1 span {
  font-size: 12px;
}
._flex_z1ykh_1 ._label_z1ykh_10 {
  font-size: 14px;
}
._flex_z1ykh_1 ._underline_z1ykh_13 {
  text-decoration-line: unset;
}

/* app.vue(グローバルなセレクタ) */
.grid {
  display: grid;
}
.flex {
  color: green;
  font-size: 10px;
}
.flex span {
  color: #00f;
  font-size: 10px;
}
.flex .label {
  color: red;
  font-size: 10px;
}

Scoped CSS は元の class 名が残り、グローバルなセレクタと合わせて適用されてしまう。
コンポーネントの一番外側の要素のクラス名をプロジェクト内でユニークにすることで対策可能。

だが、コンポーネント作成するたびに名前を意識するのも億劫のため、CSS Modules を使った方がよさそう。

2
0
0

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
2
0