2022/12/27

CSSカウンタ+CSS変数で通し番号リストの装飾パターンを量産

※HTML/CSS/JS関連のエントリのうち、IE終了により公開する意味がなくなったもの、あまりにも勉強中すぎる内容のものは適宜削除しています。検索→Twitter→ここ というルートでやって来たのに記事が無かった方はすみません。

案件および制作体制の規模的に、日頃の業務ではTailwindを選ぶメリットが皆無で、BEMも必要ないし使いたくない身であるワタシは、相変わらずオレ流テンプレートをいつしかフレームワーク並みに発達させたものを使っている(ちなみにこのサイトのbase.cssは既にだいぶ古い)。
便利な汎用コンポーネントみたいなのを思いついても、いかにもありそうなものなら既にTailwindにそんなことができるクラスがあったりして、個々人が車輪の再発明をすることもいよいよ無くなってきている気がする。というかflexとgridが便利すぎて、かつてのように「思うようなレイアウトが実現できずにウンウン悩んだ挙句検索しまくると、誰かが天才的なソリューションを自身のブログに書いているのを発見して命拾いする」的なシチュエーションはもうほとんど発生しないのではなかろうか。
そんな中で、Tailwindからそのまま転用するのは難しそうなニッチなケースがあったので書いておく。

SASSすらカスらない中小規模・旧世代コーダーの救世主といえばCSS変数。
メディアクエリのブレイクポイントに使えないことだけ残念だが、あとはcalc()の中でもどこでもだいたい使えて本当にありがたい。
olタグなんかの通し番号を自由に装飾したいときに使う「CSSカウンタ」=counter() の中にも使えるかどうか試したところ、いけた。ここを変数化すると、最小限のコードで装飾のパターン違いをいくらでも量産できる。

例では、クラス名が必ず「brachet-」+数字(または任意の何か)となる運用を仮定して4パターンの装飾を作る。通し番号部分の表示結果は以下のとおり。

.brachet-1: 両カッコ (n)
.brachet-2: 片カッコ n)
.brachet-3: 大カッコ [n]
.brachet-4: コロン n:

以下、CSS。

/* 共通スタイル */
[class*="brachet-"] {counter-reset:var(--counter); list-style:none; padding-left:2.5em;}
[class*="brachet-"] > li:before {counter-increment:var(--counter) 1; display:inline-block; width:1.8em; margin:0 .7em 0 -2.5em; text-align:center; white-space:nowrap;}

/* 装飾 */
.brachet-1 > li:before {content:"(" counter(var(--counter)) ")";}
.brachet-2 > li:before {content:counter(var(--counter)) ")";}
.brachet-3 > li:before {content:"[" counter(var(--counter)) "]";}
.brachet-4 > li:before {content:counter(var(--counter)) ":";}

/* カウンター変数指定 */
.brachet-1 {--counter:brachet1Num;}
.brachet-2 {--counter:brachet2Num;}
.brachet-3 {--counter:brachet3Num;}
.brachet-4 {--counter:brachet4Num;}

/* 入れ子対策(2階層まで想定) */
.brachet-1 .brachet-1 {--counter:brachet1Num_2;}
.brachet-2 .brachet-2 {--counter:brachet2Num_2;}
.brachet-3 .brachet-3 {--counter:brachet3Num_2;}
.brachet-4 .brachet-4 {--counter:brachet4Num_2;}

万が一同じクラスで入れ子にすると、counter-resetによって途中で数字が狂ってしまうため、親に同じクラスがあるときは違う変数が割り振られるように一応保険をかけておく。
パディング値が共通なので、番号に続くテキストの頭が勝手に揃うのがよいところ。(むろん個別に調整も可能)
Tailwindでは@applyなるものを使って同様のことができるようだけど、ビルドいらずで素のCSSに書けてしまうという点で、今回のようなコードもまあまあ意義があるのでは。

といっても、こんなに通し番号の装飾が何パターンも必要なケースはそうそう無いだろうけども。
九分九厘箇条書きしかない学生便覧とかその手のページで、いいだろうと思ってただのolを使って提出したら「カッコで囲む」「マルで囲む」等の厳密な赤入れが戻ってきてゲンナリしている向きはご活用をば。