CSSの設計(OOCSS, BEM, SMACSS, FLOCSS)

開発人数が多く、規模の大きいプロジェクトほどCSSは破綻しやすくなります。破綻を防ぐためにいくつかの設計手法が提案されています。ここでは、CSSの設計で「目指すべき状態」と「各種設計手法」について整理します。

CSS設計で目指すべき状態

https://philipwalton.com/articles/css-architecture/ にて、目指すべき状態を4つあげています。

  • 再利用しやすい
    • 同じUIが必要になったとき、すでに存在するスタイルを使いまわせるか
  • 拡張しやすい
    • 表示バリエーションが増えた時の対応のしやすさ
    • 修正箇所が広範囲にならずに対応できるか
  • 保守しやすい
    • 既存ルールに影響をださずに新しいルールを追加できるか
  • 予測しやすい
    • 何のためのclassか予測しやすい
    • どこで使われているか不明なルールが残っていないか
    • スタイルを追加したとき、期待した箇所のみに、期待通りにスタイルが反映されるか
    • htmlをみたとき、割り当てられているclassからどういった形になるか予測しやすいか

シングルクラスとマルチクラス

  • シングルクラス
    • 1つの要素に対して、1つのクラスを指定(2つ利用するケースもある)
    • class="btn-primary-large"
  • マルチクラス
    • 1つの要素に対して、複数のクラスを組み合わせて指定
    • class="btn btn-primary btn-large"
    • 役割が分かれるので再利用しやすい

主な設計手法

OOCSS
Object Oriented CSS

レゴのように考える

<div class="card">
  <img src="..." class="card-img-top" alt="...">
  <div class="card-body">
    <h5 class="card-title"></h5>
    <p class="card-text"></p>
  </div>
  <ul class="list-group">
    <li class="list-group-item"></li>
    <li class="list-group-item"></li>
    <li class="list-group-item"></li>
  </ul>
  <div class="card-body">
    <a href="#" class="card-link"></a>
    <a href="#" class="card-link"></a>
  </div>
</div>

card card-body card-title とそれぞれのパーツに対して命名してます。場所に依存せず、再利用しやすいです。

構造と見た目を分離して定義

  • 構造
    • e.g. display width height text-align
  • 見た目
    • e.g. color border-color background-color
<!-- ベーススタイル(btn) 色(btn-primary, btn-successなど) -->
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-outline-primary">Primary</button>
<button type="button" class="btn btn-success">Success</button>
<button type="button" class="btn btn-danger">Danger</button>

<!-- サイズ -->
<button type="button" class="btn btn-primary btn-lg">Large button</button>
<button type="button" class="btn btn-primary btn-sm">Small button</button>

<!-- 余白 -->
<div class="mt-1 px-2 py-3"></div>

下記クラスをそれぞれ作成しています。

  • ボタン
    • ベーススタイルクラス
    • 色、線色のクラス
    • サイズクラス
  • 余白クラス

HTML上で必要なクラスを組み合わせて形作ります。

HTMLを見た時にどう行ったスタイルになるか予測しやすいです。また、1度cssを作成すれば、HTMLとCSSを行き来せずにHTML上だけでスムーズにコーディングを進められます。

BEM
Block, Element, Modifier

Block, Element, Modifierで構成

  • 構成
    • Block
      • 構成のルートとなる要素
    • Element
      • Block内の子要素
    • Modifier
      • 変化した状態
  • MindBEMding
    • BEMのクラスの命名規則を改良
      • .Block__Element--Modifier
.navigation { }
.navigation--left { }
.navigation--right { }
.navigation__content { }
.navigation__item { }
.navigation__item--active { }

SMACSS
Scalable and Modular Architecture

  • https://smacss.com/
  • 採用例
  • コンポーネントの抽出作業をしやすくするために、指針となるカテゴリを提案
  • 構成(カテゴリ)
    • Base
      • デフォルトのスタイルでサイト全体に影響
      • 要素セレクタに対して定義する
      • normalize.cssなどもBaseに該当
    • Layout
      • ページをエリアごとに分割
      • header footer main sidebar など
      • 命名規則
        • l- で始める( l-header )
    • Module
      • 再利用可能なパーツ
    • State
      • module layout の状態
      • active hidden など
      • 命名規則
        • is- で始める( is-active )
    • Theme(任意)
      • デザインテーマ

FLOCSS
Foundation, Layout, Object

  • https://github.com/hiloki/flocss
  • 構成
    • Foundation
      • SMACSSのBaseと同じ
    • Layout
      • SMACSSのLayoutとほぼ同じ
      • SMACSSと違いgridはLayoutに含めない
    • Object
      • Component
        • 再利用可能なパーツ
        • grid button form media など
        • 命名規則
          • c- で始める( c-button )
      • Project
        • プロジェクト固有のパーツ
        • articles ranking comments profile login-form など
        • 命名規則
          • p- で始める( p-profile )
      • Utility
        • わずかなスタイル調整のための便利クラス
        • display margin など
        • 命名規則
          • u- で始める( u-mbs )