CSS設計比較（OOCSS AtomicDesign BEM SMACSS MCSS FLOCSS Tailwind）

# 背景

ちょっとグラフィカルな新規サイトのCSS設計を提案することになり、
勉強がてら、よくあるCSS設計をリサーチすることにしました。

現段階で分かっている状況は、

- 完全レスポンシブ対応
- レイアウトやコンポーネント自体はよくある形
- サムネイルが全面に押し出されたピックアップ一覧
- ちょっとグラフィカル。:hoverでアニメーションとか。
  - アニメ特設サイトほどめちゃめちゃグラフィカル！ってわけでもない。
- 規模は小さめ。基本1〜2人で実装予定。

CSS設計どうしよう？🤔


## 全体的に参考にした記事
https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a

----

# そもそも、なぜCSS設計が必要なのか？

→ないとCSSが崩壊するからです。

- 特に複数人で作業する時は、ルールがないと、各々が書きやすいように書いてしまいがち。
- 得てして、複数箇所に似たようなCSSが記述されたり。
- 可読性・保守性が著しく落ちるのは目に見えてる。
- **だから `!important` は使うなとあれほど言ったでしょ！**


# よくあるCSS設計

| 名称 |読み| なんの略か |
|----|----|----|
| OOCSS |オーオーシーエスエス？| Object Oriented CSS |
| Atomic Design |アトミックデザイン| - |
| BEM |ベム| Block Element Modifier |
| SMACSS |スマックス| Scalable and Modular Architecture for CSS |
| MCSS | エムシーエスエス？| Multilayer CSS |
| FLOCSS |フロクス、フロックス| Foundation Layout Object CSS |
| Tailwind |テイルウィンド| - |


----


# OOCSS(Object Oriented CSS)

**オブジェクト指向の考え方を取り入れたCSS**

- パーツを使いまわしてエリアに配置し、サイトを作っていく
- **パーツはどこのエリアにも依存しない**
- 構造と見た目の分離

以下のCSS設計がだいたいOOCSSの考え方を取り入れてるので
メリット・デメリットは省略します。

## OOCSS参考記事

https://qiita.com/NonGlutinousRice/items/334ec5341fe2bd224a1d


----


# Atomic Design

パーツ・コンポーネント単位で定義していくUIデザイン手法とのことです。

あ、CSS設計（実装、コーディング）というより、
デザイン寄りの話だった・・・

- Lv1:原子(Atoms)
- Lv2:分子(Molecules)
- Lv3:生体(Organisms)
- Lv4:テンプレート(Templates)
- Lv5:ページ(Pages)

というレベルでデザインしていきましょう、という思想です。

でも実装に落とせば、

- Lv1:原子(Atoms)→ユーティリティ
- Lv2:分子(Molecules)→コンポーネント
- Lv3:生体(Organisms)→プロジェクト
- Lv4:テンプレート(Templates)→レイアウト
- Lv5:ページ(Pages)→ファンデーションやHTML

って感じでキレイに分類できそうですね。


## Atomic Design 参考サイト

https://design.dena.com/design/atomic-design-%E3%82%92%E5%88%86%E3%81%8B%E3%81%A3%E3%81%9F%E3%81%A4%E3%82%82%E3%82%8A%E3%81%AB%E3%81%AA%E3%82%8B

https://qiita.com/t0daaay/items/14bcad84bb86cdd622d1



# BEM(Block Element Modifier)

設計方法というより、**クラス名の命名規則** の話

- Block -- 大枠となる独立した要素
- Element -- Block内の要素
- Modifier -- BlockやElementのスタイル

以下のようなルールでクラス名を決めます。

- BlockとElementはアンスコ2つで区切る
- Elementとmodifierはハイフン2つで区切る
- 複数単語はハイフン1つで区切る
- Block無しElementスタートのクラス名は無し
- Modifierのみクラス名はありらしい
- なるべく単語は省略しない（×btn→◯button）

## BEM例

`class="This-block__that-element--nice-modifier"`

ぼくが採用したときは、

- 複数単語はハイフン1つの代わりに、BlockはUpperCamel、elementとmodifierはlowerCamelで書く

なんてルールにしていました。（マイナーなので推奨しませんが）
BとEとMの要素が気持ち見分けつきやすくなります。

`class="ThisBlock__thatElement--niceModifier`



## BEMメリット

- **割と標準の命名規則**
  - 採用しているところが多く読める人多い。
- クラス名見るだけで役割が分かりやすい
  - 特にSCSS/SASSで入れ子でクラス名書く時便利。

## BEMデメリット

- げんなりするほどクラス名が長くなる
  - CSS側はSCSS/SASS採用でなんとかなる（というか必須）
  - HTMLでclass指定側はどうしてもごちゃる。
- ブロックinブロックにするか、エレメントにするか迷う


## BEM参考記事:

https://qiita.com/takahirocook/items/01fd723b934e3b38cbbc

https://qiita.com/merotan/items/edccde6bfbd9740570d8

----

# SMACSS

1.ベース -- サイト全体で要素そのもののデフォルトスタイルを定義（Normalizeか？）
2.レイアウト
3.モジュール -- ロゴ、ナビゲーション、タブ　などページ構成するパーツ全て
4.状態（ステート） -- `.is-hidden`とか。Readmoreを押す前とかテキストエリア押す前はボタン押せないとか
5.テーマ -- 色に関わる部分

に分類して、それに準じた名前をつける


## SMACSSメリット
- BEMじゃないので、クラス名をシンプルにできる
- モジュールが広い、逆に、「これってComponent？Project?」とか悩まなくていいかもしれない。


## SMACSSデメリット
- いやでもさすがに、モジュールが広すぎない？


## SMACSS参考記事
https://qiita.com/matsui-a/items/9b9188904d160a3ec223

https://freelance321.com/css3/smacss/#outline__3

https://qiita.com/seito2014/items/fa9b708f7cb72210bc23

# MCSS（Multilayer CSS）

- BEMとOOCSSを元に作られている
- CSSを以下の順番で上書きしていくよ！という考え方

1.Foundation（最下層）　-- normalizeとか
2.Base -- ボタン、フォーム、ナビゲーションとか
3.Project -- Baseを組み合わせたパーツ、登録フォームとかログインエリアブロックとか
4.Cosmetic（最上位） -- リンクカラー、グローバルなModifier、例外的なマージンとか
5.Context -- 特定ブラウザ/デバイス向けの記述

メリット・デメリットはFLOCSSでマージされているので割愛。

## MCSS参考記事
http://www.code-magagine.com/?p=15705

----

# FLOCSS(Foundation Layout Object CSS)

**FLOCSS = BEM + OOCSS + MCSS + ファイル命名規則**

- Foundation
- Layout
- Object
  - Component
  - Project
  - Utility

に分類し、
クラス名だけじゃくファイル名も定めたCSS設計です。

なんかMCSSにファイル命名規則も厳格にした、という理解です。
MCSSはBEMとOOCSSなので

FLOCSS = BEM + OOCSS + MCSS + ファイル命名規則

って感じになります。

## FLOCSSメリット
- 単純にいままでの設計のいろんなところのいいところどり
  - クラス名みれば役割明確、名前衝突の危険性ほぼゼロ
- 採用プロジェクトが多いので経験者多い（ぼくも経験あり）


## FLOCSSデメリット
- 今までの設計のいろんなデメリットも盛り盛り
  - クラス名長すぎ問題
  - **ComponentとProjectどっちにする問題**
    - チーム内すり合わせが必要だと思う部分
- CSS設計初学者にとっては、BEM、OOCSS、MCSS、ファイル命名規則、とそれなりに学習コスト高めかも


# Qiitaでの記事数比較

2022.8.6 10時現在

| 名称 |Qiita記事数|タグ数
|----|---:|---:|
| OOCSS |189|18|
| BEM |694|145|
| SMACSS |213|25|
| MCSS | 28| 1|
| FLOCSS |181|41|

FLOCSSとSMACSSに知見が溜まっていそうですね。

----

# Tailwind CSS

**逆に考えるんだ、「CSSなんて書かなくてもいいさ」と考えるんだ**

Tailwind CSSはCSS設計思想ではなく、
CSSテンプレートです。

しかし、**CSS設計の根幹に関わる部分をぶっ壊して**いて
しかもかなり人気なので、今回紹介します。

| 名称 |Qiita記事数|タグ数
|----|---:|---:|
| Tailwind |734|7|

Tailwindは
**ユーティリティファースト**の考え方で設計されています。

ユーティリティファーストとは、
FLOCSSでいうユーティリティオブジェクトを大量に用意し、
ユーティリティクラスだけでスタイルを実現しようぜ！って考え方です。

Tailwind実例で遊んでもらうと分かりますが、

https://play.tailwindcss.com/

![スクリーンショット 2022-08-06 10.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/158747/a6cae636-4256-92c1-7128-4bb5c584a575.png)

↑を作るのに必要なCSSはなんと

```css:css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

ほぼ**なんも書いてない！！**

その分、HTMLのクラス名は複数クラスが乱舞しております。

```html:html
<div class="relative flex min-h-screen flex-col justify-center overflow-hidden bg-gray-50 py-6 sm:py-12">
  <img src="/img/beams.jpg" alt="" class="absolute top-1/2 left-1/2 max-w-none -translate-x-1/2 -translate-y-1/2" width="1308" />
  <div class="absolute inset-0 bg-[url(/img/grid.svg)] bg-center [mask-image:linear-gradient(180deg,white,rgba(255,255,255,0))]"></div>
  <div class="relative bg-white px-6 pt-10 pb-8 shadow-xl ring-1 ring-gray-900/5 sm:mx-auto sm:max-w-lg sm:rounded-lg sm:px-10">
    ...
  </div>
</div>
```

## Tailwindメリット（憶測）
- 覚えてしまえさえすれば、**爆速**で書けそうなイメージ 
　　- 似たようなコンポーネント、テーマを (https://tailwindcomponents.com/) などから探してきてコピペできる。そこからカスタマイズすればいい。
　　- クラス名考えなくてもいいのも便利。
　　- 故に、スタートアップ・プロトタイプ開発にはメチャ向いている？

## Tailwindデメリット（憶測）
- 学習コスト高そう・・・
- クラス名短い代わりに、超複数クラス書くので、結局クラスがゴチャるというBEM問題解決になってなくない？そうでもない？
- Component化しないと、デザイン変更時の保守性ヤバない？
  - next.jsなどのFW側で、ブロックをコンポーネント化するなら、そこに書けるから問題ではない？
- Tailwindで実現できないことがあったら結局生CSS書くよね
  - （高確率でどこかは発生すると思う）
  - どこに、どう書く？
- ネット見るに、好き嫌い激しそう
  - OOCSSから伝わるCSS設計の概念をデストロイしているので。
  - でも、「好き」がいるということは、機能するシチュエーションもあるというわけで・・・

## Tailwind参考記事

https://tailwindcss.com/

https://qiita.com/y-suzu/items/496be157add1eee07274

https://blog.photosynthesic.jp/2022/05/next-js-tailwind-css-typescript-storybook-tailwindcss-classnames/


----

# 結論

CSS設計に限りませんが、「銀の弾丸」はありません。
プロジェクトの性質にあったCSS設計を選ぶことが非常に重要です。

今回のケースでは、

- 完全レスポンシブ対応
- レイアウトやコンポーネント自体はよくある形
- サムネイルが全面に押し出されたピックアップ一覧
- ちょっとグラフィカル。:hoverでアニメーションとか。
  - アニメ特設サイトほどめちゃめちゃグラフィカル！ってわけでもない。
- 規模は小さめ。基本1〜2人で実装予定。

ということだったので、kugyu10の現時点での結論は、


## チャレンジングだけど Next.js + Tailwindをイチオシ!!
- 今回の規模感、デザインには向いているかと
- クラス名考えなくていいのはかなり速度向上に寄与しそう
- 弱点である冗長になりそうなところは、Next.jsが解決してくれる
- 個人的にTailwind学習したい（笑）


## 安全にいきたいなら無難なFLOCSSが二番手でオススメです
- kugyu10も経験済み
- OOCSSやBEMに触れている人にとっては馴染み深い思想

・・・

憶測が多いのでちょっとTailwindガイド触ってから、結論部は追記すると思います。