システム開発におけるCSS管理のベターな選択肢がTailwindCSSであるという話
開発現場でのCSSライブラリのデファクトスタンダードがTailwindCSSであるのに異論の余地はないと思うが、
どの現場でも導入にあたって少数の反対意見が出たり、コンセプトが受け入れられないメンバーがいることが多い。
CSSライブラリに限った話ではなくて、Webフレームワークや言語選定でも全員が同じ意見を持っているということは少ないので、導入時になぜそれがメジャーな選択肢になっているのかを説明するシチュエーションが都度発生する。
TailwindCSSを使ったことがない・なぜそれがベターな選択肢であるか理解できないメンバーへの説明のために、また自分の中での整理のために、備忘録として考えをまとめておこうと思った。
簡単にまとめると、以下のような変遷をCSS設計が辿っていったと理解している。
- 生CSSは、グローバルスコープという観点でチーム開発の現場で容易に破綻した
- CSSのグローバル問題の解決策としてローカルスコープのCSSが好まれるようになった
- UIパーツのコンポーネント化により、CSSの再利用という概念が希薄になった
- HTMLとCSSの往復作業の中で、コロケーションが好まれるようになった
- インラインで気軽にかけるライブラリがベターな選択肢として流行した
生CSSは、グローバルスコープという観点でチーム開発の現場で容易に破綻した
プログラミングにおいて、できるだけ変数のスコープを絞ることで保守性やコード可読性を高めるのは常識だ。
離れたモジュール間で連携をするためにグローバル変数を導入すると一時的には機能するが、スケールに伴って容易に設計破綻することは皆がよく知っている。(グローバル変数問題)
一方で生のCSSは当たり前のようにグローバルで扱う想定で設計されており、チーム開発の現場ではグローバルなCSSをどのように管理して手綱を握るかをルール化しようと苦労してきた。
例えばBEMのようなルールが有名だが、これまでの現場だと特に開発チームの現場においてCSS設計が破綻するのを何度も目撃してきた。
これは
- CSSの治安を維持することに関して関心が薄いWebエンジニアが多い
- グローバルなCSSの運用ルールを定めるのにコストがかかり、守らせるコストも高い
- 共通利用されているCSS修正時のデグレ懸念や、使わなくなったCSSの削除などの管理に手間がかかる
あたりに起因していると考えている。
そもそも、スタイルとコンテンツを分離するというCSSのコンセプトに対して、CSSをただのUI実装の手段として見ているWebエンジニアが多い。
また、デザイナーからのWeb UIへの要求水準が近年徐々に上がっていくにつれ、CSSは装飾としてのスタイリングツールというよりもソースコードの一部となってしまった。
Webエンジニアはデザインを忠実に再現してUI実装するために細かいCSSを一つ一つあてながらデザインとの差分を埋めていく作業に追われるようになった。
HTMLと分離された生のCSSを記述するという行為は、スタイル要素というグローバル定数を操る作業になった。
CSSを再利用すればグローバルCSSを通じて離れたUIパーツが密結合されデグレが発生しないかを注意する必要があり、そもそも目の前にあるCSSを修正しようと思ったときにそのCSSが使われている箇所をその都度検索し影響範囲を確認しなければいけなくなった。
もちろんBEMのようなルールがうまく機能している現場もあるが、私の観測範囲だと
- 静的ページの制作現場など、(Webシステムなどのように)UIが動的に状態遷移しないコンテンツを扱う現場
- 実装メンバーが1人だけだったり、あるいはコーダーのようにCSS知識に長けたメンバーに限定されるチームでの現場
に限られていたように思う。
プログラマーがCSSをメンテナンスする現場で継続的にCSSが破綻せずに設計管理・維持されている現場には、10年以上で一度も出会ったことがない。
CSSのグローバル問題の解決策としてローカルスコープのCSSが好まれるようになった
上記のような流れの中でプログラミングと同じようにローカルスコープで機能するCSSが登場したのは自然な流れだった。
CSS ModulesやScoped CSSやCSS in JSがそれである。
グローバルなCSSを扱わなくて良くなるとBEMのようなルールを徹底する必要性も薄れ、ローカル変数を定義するのと同じ感覚でCSSを扱うようになっていった。
個々人のCSS知識のばらつきにより多少汚いCSSが生まれることもあるが、ローカルスコープだからという理由で寛容に受け入れやすくなり、少し時間を確保すればリファクタリングできるケースもできてきた。
UIパーツのコンポーネント化により、CSSの再利用という概念が希薄になった
CSS Modulesなどの利用に伴い、ReactやVue.jsのようなコンポーネント指向のライブラリが普及する中で、CSSクラス名を再利用するという行為は激減した。
同じUIパーツが発生したときには、CSSの再利用でなくコンポーネントの再利用という形で繰り返しを実現すれば済むからだ。
HTMLとCSSの往復作業の中で、コロケーションが好まれるようになった
新規でタグを書くときは、CSSクラスを命名し、CSSを記述する。
一度書いたタグを修正するときは、CSSクラス名から辿ってCSSを編集する。
HTMLとCSSを往復する中で、実装者はHTMLとCSSが不可分であることに気づくようになり、CSSクラス命名という作業を不毛に感じるようになった。
インラインで気軽にかけるライブラリがベターな選択肢として流行した
やりたかったことはCSSクラスを命名することではなく、UI実装のためにCSS属性を記述することだと気づきインラインでのスタイリングが見直されることになった。
インラインCSSと見るやいなや、先祖返りだと揶揄する熟練のプログラマーがいるが、これは一見すると先祖返りに見える螺旋階段である。
動的型付け言語主流の時代から、チーム開発での安全性や保守性やCI/CD導入の流れを経て、静的型付け言語が見直されたのと似ていると思う。
つまり、
- Reactなどのコンポーネントライブラリのおかげで、セマンティックなCSSクラスによる再利用性を担保しなくて良くなった(インラインCSSのデメリットの克服)
- UI実装の要求水準が上がるにつれ、HTMLとCSSは不可分でなくなった(コロケーション = インライン記述のメリットが増した)
によってインライン記述が見直されるようになったという理解だ。
ちなみにMDNのインラインスタイルのページでは以下のように書かれている。
インラインスタイル
この方法での CSS の使用は、可能な限り避けてください。まず、 CSS の実装の中では最も保守の効率が悪いものです。
一つのスタイルを変更するために、一つのウェブページ内で複数の編集が必要になるかもしれません。
第二に、インライン CSS はプレゼンテーション用のコードを HTML やコンテンツに混ぜてしまうため、すべてが読んだり理解したりしにくいものになってしまいます。
コードとコンテンツを分離すれば、ウェブサイトで働くすべての人にとって保守が容易になります。
現場に携わってきたものとして反論しておくと、
この方法での CSS の使用は、可能な限り避けてください。まず、 CSS の実装の中では最も保守の効率が悪いものです。
知識にばらつきのある開発メンバー間で、大量のグローバルスコープCSSをHTMLと分離しながら命名規則含めて運用する際の保守性のほうが効率が悪いと感じることが多い。
一つのスタイルを変更するために、一つのウェブページ内で複数の編集が必要になるかもしれません。
Reactなどのコンポーネントライブラリを利用する前提では、発生しない。
また共通スタイル要素はCSS変数などのデザイントークンを経由することで一括管理可能だ。
第二に、インライン CSS はプレゼンテーション用のコードを HTML やコンテンツに混ぜてしまうため、すべてが読んだり理解したりしにくいものになってしまいます。
UI要素が複雑化し、HTMLとCSSが不可分になった昨今の開発ではCSSがHTMLと完全に分離している方がむしろ可読性が落ちる懸念がある。
Reactなどのコンポーネントライブラリを使うことで、適切な粒度でプレゼンテーションパーツを切り出して命名したりカプセル化することができるので、プレゼンテーションの分離はCSSによる縦分割ではなくコンポーネント化による横分割で達成されるべきだ。
一方で、デザインシステム用なグローバルに適用されるべき要素はCSS変数やglobal.cssのような場所で適切に管理すれば良いと考える。
コードとコンテンツを分離すれば、ウェブサイトで働くすべての人にとって保守が容易になります。
Web開発の現場ではHTML自体がコードとしての要素とコンテンツとしての要素を含んでいるため、HTMLとCSSを分離すると中途半端な分離になっていしまうケースが多い。
大前提として、これまでの話はエンジニアチームでWeb開発する場合にフォーカスして書いているので個人開発や制作現場ではまた話が違ってくると思っている。
ちなみに私はTailwindCSSが長期的に覇権を握るとは思っていない。
いつかはパラダイムシフトが起きて負債化するリスクももちろんあるだろう。
アニメーション記述などができなかったり、Gridレイアウトとも相性が悪いなど、使いにくい点はいくつも見つかる。
一方であえて利用できるCSS機能を制限することでチームに一定に平和をもたらすとも考えている。
タイトルにベストではなくてベターと入れたのは現実的な解として受け入れているという表明だ。