このサイトのCSSはこれまでstyled-jsxだったのですが、Gatsbyを2から3にアップグレードしたのを機に、CSS Modulesに置き換えました。
置き換える過程で、実務で必要になりような要件をどのようにクリアしていくのか体感できたので、まとめてみます。
以下、GatsbyでSCSSを利用したCSS Modulesのサンプルになります。
このサイトのCSSはこれまでstyled-jsxだったのですが、Gatsbyを2から3にアップグレードしたのを機に、CSS Modulesに置き換えました。
置き換える過程で、実務で必要になりような要件をどのようにクリアしていくのか体感できたので、まとめてみます。
以下、GatsbyでSCSSを利用したCSS Modulesのサンプルになります。
import * as styles from './index.module.scss';
<div className={styles.classA}></div>
テンプレートリテラルを使って書きます。
<div className={`${styles.classB} ${styles.classC}`}></div>
ユーザースタイルシートとかを想定して、固定のclass名を付与するなら普通に書けばOKとのこと。
<div className={`classD ${styles.classE} ${styles.classF}`}></div>
<div className={`${styles.classG}` ${isApply ? styles.classH : ''}`}></div>
インターネットではclassnamesやclsxを推奨する記事を見ますが、モディファイアがつくとしてもせいぜい1つか2つでしょうから、素朴にテンプレートリテラルで書けば十分と考えます。
ハイフンが含まれているclass名にはそのまま書けないので、括弧で囲います。
失敗する例:
<div className={styles.class-i}></div>
成功する例:
<div className={styles['class-i']}></div>
ハイフンは使わずにアンダースコア _
を使うようにすれば、これを気にせずに書けそうです。
テンプレートリテラルで書きましょう。
<div className={styles[`class${variantJ}`]}></div>
ダイナミックなクラス名にハイフンを含む場合は、ハイフンを含めないで書くと成功しました。こういうSCSSがある時に…
.hyphen-1 { ... }
.hyphen-2 { ... }
失敗する例:
<div className={styles[`hyphen-${variantK}`]}></div>
成功する例:
<div className={styles[`hypehn${variantK}`]}></div>
DOMに付与されるclassにはいい感じにハイフンが付いていました。
ハイフンは厄介ですね……。アンダースコアに寄せるのが分かりやすいかもしれません。
合体してすこし複雑になった例です:
<div className={`classK ${styles.classL} ${isApply ? styles[`class${variantM}`] : ''}`}></div>
続きまして、CSS編です。
こんなmixinを入れたファイルを作って、必要なファイルでincludeします。
// mixins.scss
@use 'sass:map';
$breakpoints: (
"sm": "(min-width: 577px)",
"md": "(min-width: 769px)",
"lg": "(min-width: 993px)",
);
@mixin mq($breakpoint) {
@media screen and #{map.get($breakpoints, $breakpoint)} {
@content;
}
}
// index.scss
@use './mixins';
@include mixins.mq(md) {
...
}
ずっとCSS in JS脳になっていたおかげで、素朴にSASSの@useをすれば良いだけというところに辿り着くのに時間がかかってしまいました。灯台下暗しでした。
グローバルセレクタは使わずに作れたら理想ですが、いちおう使えます。
.container {
:global(.children) {
...
}
}
タグ名はそもそもスコープ付きでグローバルなようです。
.container {
div {
...
}
}