各CSS設計手法を取り入れる上でのメリット・デメリットをまとめてみた

各CSS設計を、自社のサービスに取り入れる場合どんなメリット・デメリットがあるんだろう、と思って調べたので個人的なメリット・デメリットを含めてまとめました。
ちなみに弊社はSMACSSを採用していたのですが、思った以上に「似ているけれども少し違うため使い回せないパーツ」と「内容に依存するパーツ」が多かったので、そのあたり上手くクリアできる設計手法無いかなと思って探しました。

## 一覧

* [OOCSS](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#oocss)
* [BEM](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#bem)
* [SMACSS](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#smacss)
* [FLOCSS](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#flocss)
* [ECSS](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#ecss)
* [MCSS](https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a#mcss)

## OOCSS
http://oocss.org/

### 特徴

* オブジェクト指向
* マルチクラス
* 構造とスキン（見た目）を分離する  
* コンテナと内容を分離する

### メリット
* 構造と見た目を分離することにより、パーツの使い回しがしやすい
（例：btnとbtn-submitを組み合わせて投稿ボタン作るとか）
* コンテナと内容を分離するので、作ったパーツをどこでも使える。場所に依存しない。

### デメリット
* 初見だとどこで使われてるパーツかわからない
* 内容と分離するので微妙に違うパーツがあるときに作りづらいし使いづらい

## BEM
https://en.bem.info/

*  Block（塊）、Element (要素)、Modifier (修飾) の３つに分ける
* 命名規則は.block__element--modifierとする
* シングルクラス

### メリット
* どこのブロックで使われるものなのか分かりやすい
* 入れ子にならないので優先度で悩まない
* 採用してるところが多い（＝あとから入っても知ってる人が多い可能性が高い）

### デメリット
* class名が長くて慣れるまで気持ち悪い
* 名前をつけるときにBlockとElement迷う
* HTML側が見づらい
* Bootstrapと相性悪い

## SMACSS
https://smacss.com/

### 特徴

* base/layout/module/state/themeの5つにわける
* layoutとstateとthemeには接頭語をつける
* OOCSSをもっとゆるくした感じ
* マルチクラス

### ルール

|ルール|内容|
|:---|:---|
|**base**|デフォルトのスタイル|
|**layout**|エリア分けの指定（位置を指定するのはここ）|
|**module**|再利用可能なパーツの指定（主に見た目部分）|
|**state**|moduleやlayoutの状態を指定（activeやhiddenなど）|
|**theme**|デザインテーマを指定（大体色を指定する）|

### メリット
* 共通で使えるものは共通化するので使い回ししやすい
* moduleとlayoutをわけるので同じ見た目だけど位置を変えたいとき便利

### デメリット
* 場所に依存するパーツが多すぎるサイトでは良いところを活かせられない

個人的にはこのデメリット以外はわりと使いやすいなーって思いました。

## FLOCSS
https://github.com/hiloki/flocss

### 特徴
- OOCSS, SMACSS, BEM, SuitCSS, MCSS の考え方を取り入れた比較的新しいやつ
- 命名規則はBEM
- Objectを更に3つに分ける

### ルール
1. Foundation - reset/normalize/base...（ベースのCSS）
2. Layout - header/main/sidebar/footer...（ページを構成するプロジェクト共通のコンテナーブロックを定義）
3. Object
 1. Component - grid/button/form/media...（再利用可能なパーツ）
 2. Project - articles/ranking/promo...（プロジェクト固有のパーツ）
 3. Utility - clearfix/display/margin...（便利クラス）

### メリット
- ドキュメントが日本語
- プロジェクト固有パーツをComponentと別に分けておける

### デメリット
- Component にするか Project にするかで迷う

## ECSS
http://ecss.io/

### 特徴

- 大規模、長期的なPJで使うことを考えた設計手法
- 汎用的なモジュールを作ると後々複雑化するので作るべきではないとしている
- namespace/Module/Component/ChildNote/variantにわける
- 命名規則はBEMっぽい、ModuleとComponentはBlock、ChildNodeはElement、variantはModifier
- 名前空間にハイフンを足して、接頭辞として使う
- 汎用的なものは接頭辞にsw（SiteWide）をつける（けどあんまり推奨してない）

### ルール

ルールについてはうまく日本語で書けなかったのでこちらを引用させていただきました。
[ECSSの概要と考え方のまとめ](https://qiita.com/manabuyasuda/items/37523e9d0bfbad34211f)

|ルール|内容|
|:---|:---|
|namespace（名前空間）|クラス名の衝突を防ぐための接頭辞で、コンテキストやモジュールをあらわす。|
|Module（モジュール）|視覚的に認識できる個別の機能領域のもっとも大きな区分。|
|Component（コンポーネント）|Moduleに含まれる機能性を持つ部品。|
|ChildNode（子ノード）|Componentに含まれる独立した部品。|
|variant（バリアント）|Module内の部品のバリエーション、もしくは部品が動的に変化した状態。|

### メリット
-   特定の部分のデザイン変更にすぐに対応できる柔軟さのあるCSS
-   namespaceを接頭辞にするので影響範囲が分かりやすい。いらなくなったらすぐに捨てれる
-   複数人での同時開発の際はnamespaceを分けていればOKなので衝突することがない

### デメリット
- 汎用的に作らないので同じソースを何度も書いてコードが増える
- ボタンなどの汎用的に使いたいパーツをまとめて変えたいとき大変
- ルールを覚えるのが大変。（個人的には一番理解するのに時間がかかったのでメンバーが多いPJへの導入は結構大変そう）

汎用的だとあとから複雑になって困る、修正するときの影響範囲を少なくするように、という考え方なのでその部分を重視するならばすごく使いやすそうだなと思いました。

## MCSS
https://operatino.github.io/MCSS/ja/

### 特徴

- BEMとOOCSSを基に作られてる
- レイヤー別になっていて、上書きできる順番も決まっている
- モジュールに属する要素は_（アンダーバー）でつなぐ

### ルール
|ルール|内容|
|:---|:---|
|Foundation|reset.cssやnormalize.cssなど|
|Base|再利用可能な標準スタイル（ボタンやナビなど）|
|Project|ページを構成するプロジェクトモジュール|
|Cosmetic|色やサイズなど少し変化させるスタイル|
|Context|メディアクエリなどブラウザ対応をするスタイル|

※Foundation > Base > Project > Cosmetic の順でよみこむ

### メリット

- ページごとで少し異なる（元々汎用的だった）パーツの上書きがしやすい
- 上書きしていくスタイルなのでCSS設計に慣れてない人でも理解はしやすい

### デメリット

- 上書きルールをしっかりと決めておいて管理しないと大規模サイトだと修正の影響範囲が分からなくなりそう


また他にも気になるCSS設計を見つけたら追加していきたいと思います。