CSSアーキテクチャは複雑なテーマであるため、開発者にも見過ごされがちである。しかしながら、CSSをコンポーネント単位でカプセル化することにより、CSSに関わる多くの落とし穴を回避することが可能になる。この"回避策"は開発者の作業を容易にしてくれる一方で、再利用性と拡張性といったコストも伴う。
開発者がCSSクラスを定義すると、自動的にすべてのスコープに影響し、関連する全要素(とその子)が修正される。この方法は、結果を容易に推測できるような単純なアプリケーションではうまくいくが、アプリケーションやチームの規模が大きくなった途端に問題が発生し、意図しない結果が現れるようになる。
この問題の解決には、当初はBlock Element Modifier(BEM)が使用されていた。BEMはクラッシュ回避を支援すると同時に、各クラスが実行する内容を明確にする方法論であり、命名規約である。例えば"form__submit-disabled
"は、現在のフォーム内でsubmitボタンを処理し、disabled状態を適用するものであるということを示す。
しかし命名規約は徹底させることが難しい場合が多いため、JavaScriptによって実装のより容易なソリューションが提供されるようになると、開発者たちは諸手を挙げてそれを受け入れた。CSS ModulesやStyled Componentsといったソリューションは、BEMとは違うアプローチで、CSSを単一コンポーネントに含むことによって、BEMと同じ問題を解決する。
コンポーネント設計におけるクロスアプリケーションアーキテクチャの不在という問題に取り組むためには、3つの項目に対処しなくてはならない。
- UI — テーマや一般的なアプリケーションの挙動を含む
- レイアウトコンポーネント — コンテナあるいはスマートコンポーネントとも呼ばれるもので、一般的には再利用できないが、特定のシナリオにおけるコンポーネントの動作を決定する
- プレゼンテーションコンポーネント — アプリケーションを動作させる、再利用可能なコード部品。多用途性を向上させるため、含まれるロジックは最小限のものになっている
UI
UIはアプリケーション全体に影響するグローバルなCSSで定義され、2つの関心事を持つ。
1. 定数 — 少し前まではSCSSやLESS変数が使用されていたが、現在では、主要なブラウザすべてにサポートされているカスタムCSSプロファイルが使用できる。
CSSカスタムプロパティには2つの大きなメリットがある。実行時に修正可能であるため、テーマ切り替えやダークモード実現にはパーフェクトなソリューションであることと、レイアウトコンポーネント内で修正可能であるため、もっと小さなスケールでの修正がより簡単になることだ。
2. UIステートの定義は一般的に、3つの側面に分解することが可能である。
- モデファイアステート — さまざまな要素のサイズ(大/小)あるいは設計(プライマリ/セカンダリ)によるバリエーションを含む。
- ビヘイビアステート — オンラインとオフライン、ロードのような、アプリケーション全体の状態を含む。
- 仮想(pseudo)シナリオ — イネーブル/ディスエーブルのような一時的なステータスの他、
:hover
や:focus
といったCSSステートを含む。
レイアウトコンポーネント
レイアウトコンポーネントは、再利用可能なコンポーネントを特定の方法でページ上に配置することで、コンポーネントの動作を支援するものだ。従ってその責務は、再利用可能コンポーネントの特定プロパティとデザインを初期化することと、CSS GridやFlexboxなどを使ってコンポーネントの描画領域レイアウトを設定すること、の2点に分けられる。
再利用可能コンポーネント
再利用可能コンポーネントの持つロジックは極めて少ない — レイアウトコンポーネントからのデータを受け入れることと、アクションが実行された場合にイベントをトリガする(またはコールバックを実行する)ことのみだ。
コンポーネントの再利用性を確実なものにするために、最小限のロジックと設計のみを加えることにした — つまり、表示や幅、マージンといったプロパティは基本的に回避するようにしたのだ。
コンポーネントは最初に開発された時よりも多くのシナリオを処理するように要求されることも多い(複数行表示をサポートするボタンや、過剰なテキストを持ったタイトルなど)ので、難しい作業になる場合もあるが、コンポーネントが真に再利用可能であり、次に使用する場合にも書き直しが必要ないことを確実にするために必要なものだ。