経緯
css modules ファイル内に、html セレクタを直接記述したらエラーに遭遇したので、原因と解説、解決方法を簡単にまとめました。
やったこと
css modules ファイル内で、<h1>
タグ内の文字色を 黄色 にするクラス指定を追記。
import styles from '../styles/xxx.module.scss'
export default function Home() {
return (
<div className={styles.container}>
<h1>Welcome to My app!</h1> // ここの色を黄色に変えたい
</div>
)
}
.container {
padding: 0 2rem;
}
// ↓↓ 以下を追記 ↓↓
h1 {
color: yellow;
}
エラー内容
./styles/xxx.module.css:131:1
Syntax error: Selector "h1" is not pure (pure selectors must contain at least one local class or id)
シンタックスエラー。
セレクタ "h1" は pure ではありません( pure なセレクタは、少なくとも1つのローカルクラスまたは ID を含む必要があります)。
解説
上記でいう pure とは、自前で用意する .top-page-title
や #top-page
などの classセレクタ や idセレクタ を表しています。
反対に html
, body
, button
, h1
などは impure なセレクタになります。
原因
つまりエラーの原因は xxx.module.scss
という css modules ファイル内に、 impure なセレクタを記述していること。
ルールとして、css modules ファイルでは impure なセレクタは使用できません。
解決方法1
css modules ファイルに pure な classセレクタ(id でも可)を用意し、 import したうえでその style を適用してあげる。
これが基本的な使い方になります。
.container {
padding: 0 2rem;
}
// クラスセレクタを用意
.title {
color: yellow;
}
import styles from '../styles/xxx.module.scss' // import
export default function Home() {
return (
<div className={styles.container}>
// styles.title で適用
<h1 className="{styles.title}">Welcome to My app!</h1>
</div>
)
}
解決方法2
(ネストができる Sass であれば) pure なセレクタ内に記述する。
実は、pure なセレクタの下であれば、 h1等を記述することができます。
.container {
padding: 0 2rem;
// .container の中に h1 を記述
h1 {
color: yellow
}
}
コンパイル後の css
css modules の場合、コンパイルされた css は基本的にセレクタの後に hashのような値が付与されます。(下画像の__ngV3c
の部分)
css modules ファイル名の頭部分
+ _pureセレクタ名
+ __hashのような値
しかし、classセレクタ、idセレクタでない h1 や p などは、 hashのような値が付与されないようになっています。
まとめ
いかがでしたでしょうか。
css modules は css のグローバルスコープ汚染問題を回避するための一つの仕組みです。
つまり、 css modules ファイル内には、基本的に特定の対象にのみクラスを当てるような記述(つまりクラスセレクタ等を用意)をすべきで、グローバルに適用したいスタイルを css modules 内に記述すべきではないんですね。
グローバルに適用したいものはグローバルなファイルを用意して、グローバルな場所で import するようにしましょう。