DI-CODINGの仕組み
ほとんどのWebサイトは、同じ構造パターンが入れ子になった「フラクタル構造」になっています。
まず大枠として、サイトヘッダー・メインコンテンツ領域・サイトフッターに分けられます。
メインコンテンツ領域の中には複数のセクションやコンポーネントが存在しますが、これらのセクションも、見出しを「ヘッダー」として、本文を「ボディ」、その下にボタンなどが配置された「フッター」の領域として分類できます。
大枠ではメインコンテンツ領域を<main>
でマークアップするため「メイン」という語句を用いていますが、「頭・体・足」と考えたほうがイメージしやすいので、メインの内側にあるセクションやコンポーネントでは「ボディ」と表現することにします。
各セクションのボディ領域では、さらにセクションやコンポーネントが入れ子になっており、多重構造になっていることもしばしばです。
時にヘッダーやフッターの領域は省略されることもありますが、「ボディ(メイン)の中で多重の入れ子になっている」という構造は、ほとんどの場合で同じになります。
(ページネーションなど、一部の汎用的なコンポーネントはフッター領域に配置されることがあるため「ほとんど」としています)
DI-CODINGでは、Webサイトを構成する部品を、この構造に基づきながら切り分けます。
HTMLで見る構造概念
たとえばWebサイトのトップページでよく用いるコンポーネントに「新着情報」がありますが、概ねこのようなHTMLコードになると思います。
サムネイル画像や投稿日を表示する場合は構成要素が異なったり、<ul>
や<li>
を<div>
にするなどマークアップが異なる場合もあると思いますが、構造的には概ねこれが基本形でしょう。
ヘッダー領域に見出しがあり、ボディ領域に記事へのリンク一覧があり、フッター領域にはもっと多くのリンク一覧が掲載されたページへのリンクや、ページネーションが配置されます。
つまり「新着情報」というコンポーネントをコーディングする場合、どのようなデザインであっても、まず上記のようなHTMLを書き、そのあとデザインに合わせてCSSを書いていくことになります。
DI-CODINGとしてのポイントは、コンポーネントの大外にあたる要素に固有のclassをつけるということです。
上記のコードでは<div class="news">
と、その終了タグに該当します。
このとき、上記コードの<!-- 新着情報 -->
と<!-- /新着情報 -->
のように、コンポーネントの範囲をコメントで明示しておくと、なおよいでしょう。
CSSで見るコード設計概念
続いてDI-CODINGにおけるCSSコードの書き方ですが、「コンポーネントの外側に影響が出ないようにセレクタを書く」というのがポイントです。
Webサイトでは、広範囲で汎用的に同じ部品を使うこともありますが、余白、サイズ感、配色など、デザインに応じて特定の領域だけ他とは少し違いをつけることがあります。
BootstrapやTailwind CSSなど、CSSフレームワークの考え方では、こういった調整用に「ユーティリティ」となるセレクタを大量に用意してありますが、用意されていないサイズや色を使うことはできず、サイズや色を微妙に調整するのは困難です。
DI-CODINGでは「このセクションだけはこのスタイルを追加する」といったような「局所的な例外」をつけることが容易で、サイズや色も柔軟に調整できます。
外側への影響をコントロールする
たとえば、サイト全体で共通して使う汎用的なボタンのために、以下のようなCSSがあるとします。
このボタンに対して、新着情報のセクションだけは少し文字サイズを大きくしたい場合、DI-CODINGではこう書きます。
先ほど例で出した新着情報のHTMLでは、一番外側にあるのは<div class="news">
です。
つまり、.news
を起点にCSSセレクタを書けば、新着情報の外側にあるコンポーネントへは絶対に影響を及ぼすことのないコードになります。
内側への影響をコントロールする
しかし、この書き方では逆に.news
の内側にあるすべての.btn
に影響が及んでしまいます。
他のコンポーネントを入れ子にした場合、もしclass="btn"
のついたHTML要素があれば、このCSSコードが影響を及ぼしてしまうことになります。
この問題を解決するために、DI-CODINGでは様々なアプローチが用意されていますが、説明として最も分かりやすいのは<div class="news--footer">
の存在でしょう。
このコンポーネント自体を表す名前「news」の名前を継承して、新着情報のフッター領域に「news--footer」というclassで命名しているので、これを起点にセレクタを書くとこうなります。
先ほど説明したように「ほとんどの場合、入れ子になるのはボディ領域の中」なので、フッター領域を囲むclassを起点にセレクタを書けば、内側にまで影響が及ぶことはありません。
専用化する
しかしボディ領域にあるボタンの場合はどうでしょう。
コンポーネントはボディ領域で入れ子になるので、以下のような書き方では内側へ影響を及ぼす可能性があります。
この場合は「汎用的なボタンに局所的な差異をつける」という考えをあきらめて「新着情報専用ボタン」と捉え、このように書きます。
ボディ領域「news」の名前を継承して「news--btn」というclassで命名し、このclassをセレクタにすれば内側に影響が及ぶこともありません。
この場合.btn
に差異をつけたものではなくなってしまうので、上記の通りbackground-colorやborder-radiusも再度記述しないといけなくなりますが、これはSassの変数やmixin、extendを利用することで共通化することも可能です。
派生させる
Sassを利用できない場合など、どうしても専用化することに抵抗がある場合、「ボタンの派生パターンを増やす」という手段もあります。
これはCSSフレームワークに近い考え方で、.btn-large
のようなセレクタをCSSフレームワークの中で見たことがあると思います。
.btn
で共通のCSSが適用され、差分だけ書けばよくなるので、こちらのほうが手っ取り早いように思えるかもしれませんが、派生パターンを無闇に増やすと、どこでどれを使っているのか管理が難しくなります。
CSSフレームワークのように、広い範囲で汎用的に使われる.btn-large
のような派生パターンであればこちらの方法を採るべきですが、特定のセクションやコンポーネント内で局所的に差異をつける場合には、こちらの方法はおすすめしません。