CSSの3大設計手法をまとめてみた

# はじめに
皆さんは普段どのような設計手法でCSSを書いていますでしょうか？
設計手法とはHTMLのクラス名の付け方と、CSSのコードの管理方法についての手法のことです。

**超簡単にいうと命名規則というやつです。**

CSSの設計手法を取り入れることによって、メンテナンス性や作業効率を向上させることが出来ます。

# ３大設計手法
様々な設計手法が誕生し採用されています。
今回は、有名どころの３つを簡単にまとめてみました。

|設計手法  |コード量  |ファイル数  |他要素への影響範囲  |再利用性 |
|---|:--:|:--:|:--: |:--: |
|**BEM**  |増える  |普通 |小さい  |低い  |
|**OOCSS**  |減る  |普通 |大きい  |高い  |
|**SMACSS**  |減る  |増える |大きい  |高い  |

# それぞれの特徴
では、どんな設計手法なのかをまとめていきたいと思います。

## BEM
いきなりCSS設計手法の王道である BEM（ベム）さんの登場です。

最も好き嫌いが別れる設計手法であり、最も有名な設計手法ではないでしょうか。
他社のサイトをブラウザの開発者モードで覗くムッツリスケベの皆さんなら、よく見る命名かもしれません。

BEM という名前は Block、Element、Modifier の３つの要素を示しています。

**この設計手法は命名規則が大きな特徴となります。**

3大設計手法の中で、最も細かくクラス名を指定する設計手法です。
よって、スタイルの使い回しが少なく、修正時の影響範囲が小さいため、メンテナンスコストを下げることが出来ます。

ただし、これによってクラス名やファイルの記述量が長くなってしまうというデメリットもあります。

### 命名規則
BEMはクラスの所属関係を明確に宣言します。
前述した Block、Element、Modifier の3つの要素をシングルクラスで表現します。
>１つの要素に対して、複数のクラスを指定するのをマルチクラス、１つないし２つ程度のクラスを指定するのをシングルクラスと呼びます。

**Block**
`main` などの、大きなレイアウトの部分です。

**Element**
Blockの中に構成される `list` や `button` などの要素のことです。

**Modifier**
エラーメッセージのスタイルや、未入力時のスタイルなどといった状態を表すものです。

BEMにおけるクラス名は
BlockとElementは **アンダースコア2つ**
ElementとModifierは **アンダースコア1つ**
で構成されます。

しかし **MindBEMding** というBEMから派生した考え方では、
BlockとElementは **アンダースコア2つ** 
ElementとModifierは **ハイフン2つ**
で構成されます

一般的には **MindBEMding** の方が多く採用されています。

```index.html
<!-- block__element--modifier の規則で書く -->

<!-- mainで使われるボタン -->
<div class="main__button">

<!-- headerで使われるボタン（通常時） -->
<div class="header__button">

<!-- headerで使われるボタン（エラー時） -->
<div class="header__button--error">
```

このように、BEMはクラス名を見るだけで、その要素の所属情報が一目で分かるので、個人的には結構好きです。


## OOCSS
OOCSS（オーオーシーエスエス）は、「Object Oriented CSS（オブジェクト指向CSS）」の略語で、Yahoo!の開発者であるNicole Sullivanによって提唱されたCSSの設計手法です。

**簡単に言うと、再利用可能なクラス名を作って不必要なコードを減らそうってことです。**

よくあるCSSのアンチパターンですが、共通のスタイルなのに各要素に追加したことで、改修時に苦労した経験のある方は多いのではないでしょうか。

その問題を解決するように設計されたのが OOCSS です。

### 命名規則
再利用可能なスタイルはひとつのクラスにまとめるのがモットーです。

```index.html
<!-- サイズの異なるカードを表示したい場合 -->

<!-- アンチパターン -->
<div class="card_small">
<div class="card_medium">
<div class="card_large">

<!-- OOCSS -->
<div class="card small">
<div class="card medium">
<div class="card large">

```

このように `small` などのクラスはサイト内の他の箇所でスタイルを指定することができ、汎用性が向上します。

## SMACSS
SMACSS（スマックス）とは OOCSS の流れを汲んで提唱された設計思想のため、基本的にOOCSSと同じマルチクラスで構成されます。

SMACCS とは「Scalable and Modular Architecture for CSS」の頭文字を取った言葉であり、5つのカテゴリに分けるのが大きな特徴です。

**簡単にいうと、CSSファイル自体を大きくカテゴライズして、迷子にならないようにしようねって話です。**

分割したCSSファイルを `@import` などを使って1つのファイルに読み込むなどという手法も多くみられます。


### SMACSSにおける構成

**Base**
html要素やbody要素に適用するfont-familyや、aタグに適用するcolor、borderなどをまとめておきます。

**Layout**
ヘッダー・フッター・メイン・サイドバーなどの大枠のスタイルをまとめておきます。
ほかにも、グリッドなどの比較的大きなレイアウトはこっちに入ります。
小さいものはあとで出てくるモジュールカテゴリにまとめることが推奨されています。

**Module**
ボタンやリンクなどの再利用を前提とした部品をまとめておきます。
基本的に他のカテゴリに入らないものはすべてここに入れると思って大丈夫。

**State** 
状態を表すスタイルをまとめます。
フォームにエラーを出す時にinputタグの枠を赤くするなどの「状態の変化」を表すスタイルを記述します。

**Theme**
ダークモードなどのテーマに応じたCSSが入ります。

### 命名規則
レイアウトカテゴリやステートカテゴリなどに属するクラスは、`.l-sidebar` `.is-label-error` などの接頭辞をつけることが推奨されています。

レイアウトは `l` 、ステートは `is` です。

また、他に定義されているクラス名の汚染を防ぐために、ステートカテゴリのクラス名は.is-label-error、is-button-submitなど、依存する部品の名前を入れます。

# まとめ
CSSに限らず設計手法を取り入れることは、様々なメリットをもたらします。
ひとつだけを採用するのではなく、「レイアウト分離はSMACSS、クラス名はBEM」などのように、組み合わせて使用することも可能なので、これを機にチームなどで話し合ってみても良いかもしれませんね。

### 参考文献
今回も様々な文献を元にまとめさせて頂きました。
更に詳しい情報も載っているので、興味のある方は是非読んでみてください。

[有名な3つのCSS設計をまとめてみた〜OOCSS編〜](https://blog.triana.jp/?p=1704)
[有名な3つのCSS設計をまとめてみた〜SMACSS編〜](https://blog.triana.jp/?p=1884)
[有名な3つのCSS設計をまとめてみた〜BEM編〜](https://blog.triana.jp/?p=2105)
[【CSS設計手法】BEM、OOCSS、SMACSSの違いと特徴のまとめ](https://webdesign-trends.net/entry/9214)