サイトデザインの更新をCSS Modulesで進行中。CSSのアーキテクトについて考えていることなど。


サイトデザインを少し変更したくなったので変更することにしました。1 つまえのデザインは tailwind を使用していましたが、今回は色々悩んだ末、CSS modules を採用して少しずつ置き換えています。

CSS をできるだけシンプルに使いたい

このサイトで使っている CSS の技術は、styled-components から始まり emotion に変更、次に tailwind に移行しました。

React 使用時に CSS をどうやって使うのがベストか、仕事でもプライベートでも怖いくらい答えが出なくて四苦八苦しています。そんな状態なので毎度方向を変えて試して良いところと悪いところを学ぶようにしています。今回の方向性は極力シンプルに使うということです。

UI ライブラリ

Material UI や antd design、あるいは Bootstrap などを使用するとクオリティが高く、使いやすい UI を使用できます。全部作るのが大変な時や、作る必要がない時は使用した方が良いと考えています。

ただ、今回の用途とは合わないので見送り。

Atomic Design は UI 作成まで

シンプルに使うといっても CSS はグローバルに展開される機能です。適当に使うと簡単に React の Component の UI を崩壊させます。その対策に UI の作成や組み合わせの管理方法としてよくあがるのが Atomic Design… なのですが、これも React に持ち込むのは面倒なところが多いと感じています。

UI 作成時に Atomic Design の思想を用いるのは便利に思います。今回サイトデザインを更新する際は Sketch で簡易にモックを作りました。その時のパーツ分類は Atomic Design を意識しています。

"atomic design"

ただ、Atomic Design でデザインされたものをそのまま React に持ち込むのは難しいです。特にチーム開発だと UI Component を Atoms、Molecules、Organisms どれにするか問題は本当に面倒です。デザイナーが Molecules にしているから Molecules!とかすると React Component は歪に増加しがちです。

UI には UI の、React には React の設計があります。UI 設計に Atomic Design を学ぶ価値はあると考えていますが、だからといって React に Atomic Design の階層を持ち込むかは考える必要があります。とはいえ他に良い階層があるわけでもないのでそうなってしまうところもあるのですが、ブログサイトレベルかつひとり開発ならまあ必要ないです。

何も依存しない BEM

名前空間を付けて CSS の適用範囲を限定する方法で.Home__Hero-text .Home__Hero-text—spoiler のような Block、Element、Modifier の形で class 名を作るのが BEM です。React の場合は Block を Component 名にすると分かりやすい気がします。ただ、それをするとやや大きめの Component で Element の肥大化に気をつけないといけないかもしれません。.Home__Hero-right-register-btn—disabled のような Element が膨れてきたら Block を切り直す方が良いです。

Atomic Design が階層のルールなら BEM は名称のルールなので組み合わせることもできます。ただ、BEM の問題点はとにかく名前を考えるのが大変でルール的に scss を併用しないと記述量も多くみ通しが悪くなりがちなことです。名前さえテキパキ決まるなら使いやすい仕組みで、ライブラリや webpack に依存しにくいのは良いところです。

今回は名前を考えるのが嫌だったので見送りました。

tailwind

Utility-First という考え方のアプローチで人気なライブラリ。クラス名を考える必要がなく、自分で class を作ることも減ります。また、PurgeCSS で不必要な class を削除して使用していない class の容量削減も簡易に可能と色々モダンです。

現時点での CSS アーキテクトの選択としてはかなり正解に近いのでは!と感じます。ただ、裏付けがあるわけではないですがまだ 1 つか 2 つか発展した形が出てきそうという点、仕事で使ったり、選択するのはしばらくなさそうということで今回は見送ることにしました。

CSS Modules

class 名称を hash にし Component に閉じたものが生成されます。良いところは同じような class 名称を深く考えることなく使いまわせることです。.container、.title のようなありふれた class 名をユニークにしてくれます。

一方で、class 名称が hash になってしまうので親要素からの上書きに難があるように感じます。特定の親要素から特定の css をオーバーライドするといった作業に手間が増えます。

また、hash 化する仕組みが必要になり、大体は Webpack やその plugin に依存します。そのため Webpack 周りのアップデートリスクを内包すると書いている人もいます。実際にどれくらいリスクがあるのかを体感したいところもあり、名前を考えるコストも低そうなので今回は CSS Modules を使ってみることにしました。

適用範囲が明確で、名前をつけるコストが低いものが求められている

どのような CSS のアーキテクトであれ、必要なのは自分が制御した範囲にスタイルを当てやすいことと、他の UI が不意に破壊されないような仕組みを入れることです。また、そうなってくると class の名前をつけるコストがとても高くなりがちなのでそこは極力自動化するテコ入れが必要になります。

styled-components や emotion はフロントエンドエンジニアが全部作るという前提ならかなり優れていますが、サーバーサイドレンダリングにやや不安があるのと、もう少し分業が進んだ形態だと厳しいところも出てきます。例えば HTML や CSS はある程度わかるけど React は厳しい、JavaScript は得意でないデザイナーも UI 部分だけ作成したいような環境だと、React に寄った実装を求められるものより、通常の css がかける環境の方がやりやすいはずです。

CSS は難しい

CSS をどうやって書いていくべきかを長らく悩んでいます。フロントエンドというと JavaScript や TypeScript の話がメインになる昨今ですが、UI の作成が絡む以上、HTML や CSS の使い方も重要なトピックです。

CSS 修正は影響範囲が読みにくく、UI のちょっとした崩れは機能的な不具合として認知されにくいため人力のテストが普通に通ってしまいがちなあたりも怖いところです。数 px のズレに違和感を持てるかは訓練か才能のどちらかが必要になると思います。

ちょっとしたズレや歪な実装が積み重なった結果、少しずつ増え続けた火種が突如炎上するような開発はとても怖いです。一旦燃えてしまうと火を消すのは結構な地獄で痛みを伴います。

CSS の扱いはとても難しいと感じています。なので、個人サイトや個人ブロダクトで積極的に練習していくつもりです。