HubSpotやCSS設計に明るい半田のウェブサイトです。
ウェブサイトの本質は情報を伝えることですので、それを言い訳にデザインは全体的に工事中です。

CSS設計とは何だったのか?と、コンポーネント環境との関わり

シェア:

みんな大好き、あるいは大嫌いなCSS設計。そんな言葉が生まれてから久しく、JavaScriptフレームワーク(以後JSフレームワーク)を始めとする技術が提供するスコープ付きのコンポーネント環境の登場によって、そのなりを潜めている気がしなくもない。

そんなCSS設計とは何だったのか、をちょっと小難しく振り返ってみます。

なお本記事では、区別のためCSS設計が「再利用可能なパーツ」とみなす単位を(あるいは慣習的に)「モジュール」、JSフレームワークにより提供される単位を「コンポーネント」と呼びます。

CSS設計が行っていたこと

「CSS設計」と聞くと Block__Element–Modifier という形式の長ったらしいクラス名を付けることだ、とパッと思うかもしれません。しかしこれはCSS設計が行っていたことのごく一部に過ぎず、CSS設計が行っていたことを大別すると次のようになります。

  1. カスケード設計
  2. モジュール設計
  3. 名前設計
  4. スタイリング設計

これらについて、それぞれ見ていきます。

カスケード設計

カスケード設計では、まずCSSにグループ/レイヤーという概念を導入することで、コードの順序を管理することを狙います。これは主にSMACSSやFLOCSS、PRECSS、ITCSS等に見られる手法で、

  1. reset
  2. base
  3. layout
  4. modules / components
  5. utility

のような形で、スタイリングの目的に合わせてCSSを分類します。そして、後に行けば行くほどカスケードの力関係が強く、下部のレイヤーは必ず上部のレイヤーのスタイリングを上書きできる、という思想を多かれ少なかれ提供します。

また、セレクタ利用のルールを統一すること、一言で言えばクラスセレクタの利用を基本とする、という考え方も、このカスケード設計の一部と言えます。

つまりカスケード設計が行っていたことは、「重要度や詳細度を管理することで、期待通りにスタイリングする」ということであり、プログラミング一般の考え方に照らし合わせると予測可能性の設計である、と言えます。

プログラミングにおける予測可能性とは、 プログラムの動作や出力が事前に予測できることを指す。予測可能性が高いプログラムは開発者が 意図した通りに動作することが期待できる。またコードがわかりやすく読みやすいため、修正や拡張が容易である。

Claude 3 Opusによる

モジュール設計

CSS設計の次の仕事であるモジュール設計は、主に「ビジュアルをどのように分解し、どのような粒度でモジュールとして独立させるか」という設計を指します。

わかりやすく例を挙げると、例えば同一ウェブサイト内の異なる10ページを10人がよーいどん、で一斉に構築をすると、10ページの構築にかかる合計時間は肥大化し、非常に効率の悪い進め方となるでしょう(並列処理をしているので、完了までの時間は短いかもしれません)。なぜなら、ボタンなどの共通パーツを、全員がそれぞれ構築してしまうからです。

この状況を防ぐためにモジュール設計が存在します。共通である、あるいは再利用可能な部分をなるべく小さい単位で見い出し、全体の構築を容易・効率的にするのがモジュール設計の役割です。

(現実問題としては、既に構築済みのボタンのスタイリング設計 - 後述します - が悪いと、このボタンモジュールを再利用しようと頑張るより、それぞれが別々にボタンを構築してしまった方がかえって早いかもしれません。設計が下手だとそんなこともあり得る訳ですが、それは原因がCSS設計ではなく人間のスキル不足にあるため、ここでは別問題とします)

ここでもプログラミング一般の考え方に完全に一致ではないにせよある程度照らし合わせると、つまりモジュール設計が行っていたことは分割統治の設計である、と捉えることができます。

分割統治法(divide and conquer algorithm)とは、 大きな問題を効率的に解く手法の一つで、 問題全体を同じ構造の小さな問題に再帰的に分割していき、 簡単に解けるサイズにした上で解いていく方式。

https://e-words.jp/w/分割統治法.html より

名前設計

次にCSS設計と言えばこれ、みんな大好き(大嫌い)名前設計です。モジュールの親要素の名前を子要素に継承( Block__Element 方式)させることで擬似的にスコープを形成しスコープを防ぐことを目的とします。

またそれだけでなく「そもそもモジュールにどういった名前を付けるか」というのもこれに該当します。料金を示すボックスが3カラムに並んでいるのをコンテンツやコンテキストと密結合にして「 price-list 」と名付けるのか、疎結合にして「 cards 」とするのか、みたいな話です。「名が体を表すために、名をどうする」ですね。

これは言わずもがな、プログラミング一般の考え方においても名前空間の設計に近いと言えます。

名前空間(namespace)とは、各要素に一意の異なる名前を つけなければ識別できない範囲のこと。また、名前の集合全体を小さな空間に区切り、 それぞれに異なる識別名を与えることで、 その空間内では他の空間に含まれる名前の競合・衝突を 意識しなくて良いようにしたもの。

https://e-words.jp/w/名前空間.html より

スタイリング設計

最後にスタイリング設計です。これは1番泥臭いというか経験則が支えになる部分で、「モジュールとしての機能を十分に満たすために、モジュールのルート要素にどういったスタイルを当てないべきか」を管理するものです。端的に言えばよくあるモジュールのルート要素に margin を付けるな、問題がこれに当たります。もっとわかりやすく言うと、ボタンモジュールに position: absolute が付いていると再利用の度に position プロパティを付け直さなければならない、とっても使いづらいボタンの完成です。

またスタイリング設計はそれだけでなく、「モジュールの子要素はどのように制御すべきか」も管理します。要するにモジュールの子要素に対してはモジュールの外側からスタイリングしようとするな、という話で、この辺りの話はPRECSSのドキュメントのAdvance Caseとしてまとめているので、いまいち想像が付かない方は合わせてご覧ください。

これはつまりプログラミング一般の考え方で言えば「関心の分離の設計」に近しいものになります。

システムを明確で単一の責任を持つ 構成要素に分割するという設計の原則。各構成要素は、他の構成要素の動作に 依存せず自身の責任に集中する。これによりシステムの理解性、再利用性、保守性が向上し、 変更の影響範囲が限定される。

Claude 3 Opusによる

つまりCSS設計が行っていたこととは

CSS設計が行っていたことを、4つに分けて解説しました。またそれぞれに対して毎度わざわざプログラミング一般で言えばどういった概念が近いかも添えました。

つまり何が言いたかったかと言うと、端的に言ってしまえばCSS設計が行っていたこととはビジュアルとコードの間で

  • 予測可能性の設計
  • 分割統治の設計
  • 名前空間の設計
  • 関心の分離の設計

をしていた、ということです。

かくして、CSS設計によって人類はCSSを御する力を手に入れ、CSS界隈には平和が訪れたと思った?残念でした!きちんと行うには、CSS設計はあまりにも複雑過ぎたのです。一応セオリー通りに頑張れば誰でも6割くらいは出来ると思いますが、その先をどこまできっちりできるかは、はっきり言ってこれは適正の世界です。

しかもウェブデザインというのは建築デザイン等と違い、物理法則がありません。物理法則がないので、論理的合理性が働く力も必然的に弱くなりがちです。論理的合理性が弱いものの中から、それでもパターンを見出し、コードという論理的合理性の塊に押し込めるのは、かなり骨の折れる作業です(普通は無理矢理押し込められる方の骨が折れそうなもんですけどね。この場合骨が折れるのは押し込める方です)。

そんな中、JSフレームワークによるスコープ付きのコンポーネント環境が登場しました。

コンポーネント環境が吸収したこと

コンポーネント環境が登場したことにより、CSS設計というのはフロントエンドエンジニアの関心ごとではなくなり、若干なりを潜めたように思います。なぜそうなったかと言うと、CSS設計が本質的に担っていた

  • 予測可能性の設計
  • 分割統治の設計
  • 名前空間の設計
  • 関心の分離の設計

の幾つかは、コンポーネント環境が代わりに担うようになったためです。ただし全部が全部コンポーネント環境が担ってくれたかと言うとそうではなく、むしろまともに担ってくれたのは1つ程度だったりします。

ので、現代のフロントエンドエンジニアが気にすべきポイントは、SFC / CSS Modules / CSS in JS / Tailwind CSSなどCSSの書き方もさることながら、「CSS設計が担っていたがコンポーネント環境が担っていない範囲、及びその狭間で曖昧になっているもの」を楽観視しないこと、というのが私の持論です。

コンポーネント環境が担う範囲

  • 名前空間の設計(名前設計)
    • スコープ機能により、スタイリングのための名前はほぼ気にしなくてよくなった
    • なんなら要素型セレクターを使ってもよい
    • コンポーネント自身にどういう名前を付けるかは、引き続き後悔のないように考えましょう

どちらとも言えない範囲

  • 予測可能性の設計(カスケード設計)
    • スコープ機能により、よっぽど特大コンポーネントを作っていない限りは詳細度はそこまで気にしなくてよい。詳細度を気にしなければならない状況の場合は、むしろ肥大化したコンポーネントを見直しましょう
    • しかし、コンポーネントの手前の reset / base / layout というような レイヤー分けの発想は引き続き重要。さすがにここを疎かにすると、開発がカオスになります
  • 分割統治の設計(モジュール設計)
    • 「ビジュアルをどう分解するか」という観点は引き続きCSS設計の知見が活きる
    • ただし、特にウェブアプリなどのコンポーネント環境の場合はここに「機能単位で見た場合の粒度」も加わるため、 CSS設計の知見だけでは足らない
    • ビジュアルと機能の両方を見ながら、コンポーネントを切り出していく必要がある

コンポーネント環境が担わない範囲

  • 関心の分離の設計(スタイリング設計)
    • 「コンポーネントに直接当ててはいけないスタイル」や「子要素の制御の仕方」 を理解していないと、使いづらい負債コンポーネントが簡単に出来上がる
    • コンポーネント環境により子要素を外から無理矢理制御する、なんてことはしづらくなったが、それでもやろうと思えば出来てしまうので注意

まとめ

以上、駆け足でしたがCSS設計とは何だったのか?と、コンポーネント環境が登場して、CSS設計はどうなったのか、コンポーネント環境が何をしているのか、をざっくり解説しました。

なおこの話を、Tailwind CSS等も交えてにCSS Niteにてオンラインでお話します。当日の視聴は無料、スライド・アーカイブ付きのチケットもありますので、興味のある方はぜひご登録ください!

“コンポーネント” が登場してCSS設計はどう変わったか? - CSS Nite | Doorkeeper

シェア:

コメント

関連記事