- 現在: 汎用&コンポーネントなセレクタ含めて、グローバルな 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 を使った方がよさそう。