新しめのCSS設計まとめ 〜2016年冬〜

最近新たに色々なCSSの設計が提唱されているので、学習を兼ねて簡単にまとめました。

どれも実際に実践してないものばかりなので、表面を舐めたいなくらいの気持ちで読んでください。
ググればもっと詳しく解説してくれている良記事があります。

# 以降のCSS設計へ影響を及ぼした３大アーキテクチャ

派生したCSSの設計たちは、ほぼこれらの考え方に影響を受けている。
はじめに簡単におさらい。

## OOCSS

米Yahoo!のNicole Sulivan氏提唱。
構造と見た目を切り分けて考える。オブジェクト指向型CSS。

```css
.box {
    width: 100px;
    height: 100px;
}
.box-red {
    background-color: red;
}
.box-blue {
    background-color: blue;
}
```

## BEM

ロシアの検索エンジン大手Yandex社による考案。
要素と子要素と修飾子に分類してclass命名を行うルール

```css
.block {
  width: 100px;
}
.block__element {
  width: 20px;
  margin-left: 10px;
  color: blue;
}
.block__element--modifier {
  color: red;
}
```

## SMACSS

Jonathan Snook氏提唱。
CSSを以下のようなレイヤーに分割して定義していく。

- Base
- Layout
- Modules
- State
- Theme

# APBCSS (Atomic Parts Base CSS)

http://apbcss.com/

AtomicDesignの考え方を中心に据えたCSS設計

一番小さな構成要素である原子パーツ（Atoms）はレイアウトに関する指定はせずに、非常に抽象的で汎用性のある部品として定義する

```scss
.icon {
  display: inline-block;
  &.social {
    width: 34px;
    height: 34px;
    background: url(SpriteImagePath) no-repeat;
    @include background-size(205px auto);
    &.github { background-position: -171px top; }
  }
}
```

Atoms同士を組み合わせてつくられる分子パーツ（Molecules）もレイアウトの指定はしませんが、内包されるAtomsにはレイアウトが発生します。

```scss
.btn {
    .icon {
        &.social {
            margin: 0px 6px -11px -34px; // Molecules内にあるAtomsの配置指定
        }
    }
}
```

このように順々に層を厚くしていき、内包する部分のレイアウト指定のみに絞っていく。

---

レイヤー構造は以下の通り

- Atomic：原子パーツ名となるクラス名
    - （txt/icon/btnなど）
- Module：UI を包括するモジュール名となるクラス名
    - （header/footer/xxxBoxなど）
- Skin：装飾などのクラス名
    - （red/blueなど）
    - class="btn red"のようにマルチクラスで使用
- Number：ナンバリング用のクラス名
    - (one/two,no[nth],first/lastなど)
- State：状態を表すクラス名
    - (active/disabled/checked/right/center/note)
    - 右寄せ・中央寄せや、文字サイズの小さい注意文言などもStateとして表現
- Other：その他のクラス名。パーツのセマンティックネームもここに含む。
    - (wrap/ServiceName/)
    - 固有のサービス名詞を使う場合や、特定の名前空間の定義もココ

---

class名の命名については特に指定は無し

# MOCSS

http://qiita.com/nabepon/items/672b40647acc38dc97bb

以下の5つのレイヤーに分割

- Common
    - (reset/theme/clearfixなどのutil系など)
- Model
    - 抽象化されたmixinの集まり
    - 再利用の可能性があるものは、ここに集約
- Package
    - 特定の画面グループ毎に名前空間をつくる役割
- Component
    - mixinのincludeを行い、Modelの実体化を行う
    - Packageの名前空間内に展開していく
- Page
    - 例外的なページ固有の調整用

```scss:Model
@mixin fooModel() {
  .title {
    font-size: 18px;
  }
}
```

```scss:Package/Component
.package { // 名前空間

  .fooComponent {
    @include fooModel;
    margin-top: 8px; // レイアウト調整
    padding: 0 8px; 
  }
}
```

Modelにひたすら要素の定義を行い、Packageという単位でコンポート実体化を行っていく感じ。
Packageの分け方と、高品質なModel化にわりと知識と習熟が必要になりそう。


# ECSS (Enduring CSS)

http://ecss.io/

OOCSSによって生まれた複雑性を解決したい手法。
例え冗長な記述になったとしても、抽象化はあえて行わない。

あまり奇をてらったことはせずに、根付いている考え方に最低限のわかりやすいルールを添えてるだけの印象でした。

---

特定のテンプレート単位に完全にCSSを分けて作ってしまう(template)
それとは別に横断的につかえる汎用部品を別途つくります(structure)

ただしここでいう汎用部品とは、ボタンやアイコンなどの小さいものではなく、
ヘッダやフッタなどの、共通に表示させたいUIエリアレベルのものを指しているようです。

```
src/
  css/
    template/
      top/
      search/
      article/
      help/
      ...
    structure/
      header/
      footer/
      ...
```

以下のように接頭辞を用いて、堅牢性をもたせます。

- top -> top-*
- search -> srh-*
- header -> hd-*
- footer -> ft-*

ここまでのディレクトリや接頭辞は一例であり、構造思想が沿っていればこの限りではありません。

接頭辞以降の命名はほぼBEMと同じです
`xx-Component_Node-variant`

```html
<div class="srh-SelectFoo">
  <ul class="srh-Menulist">
    <li class="hd-Menulist_ListItem">...</li>
    <li class="hd-Menulist_ListItem hd-Menulist_ListItem-active">...</li>
  </ul>
</div>
```


# ITCSS (Inverted Triangle CSS)

https://speakerdeck.com/dafed/managing-css-projects-with-itcss

詳細度を重視しており、以下のような詳細度の高さを基準にしたレイヤーで構成される。

- Settings
    - (変数/設定)
- Tools
    - (mixin/function)
- Generic
    - (normalize/reset/ユニバーサルセレクタなど)
- Base
    - (html/bodyなど)
- Objects
    - OOCSSで言うオブジェクト
- Components
    - 要素が実際に使われることを想定した状態になる（装飾や状態）
- Trumps
    - ヘルパークラス。!important使用可能

上記が基本だが自由に増減することを許容しており、スケールすることが可能。
Baseより下の階層では、要素型セレクタの使用を禁止している。

ObjectsとComponentsの切り分け方にやや難しさがありそう。

詳細度を明確にするため、CSSファイルはパーシャル化したのちに、
上から順番にimportするようにすること。

# ECSSIST (Extensible CSS Idealistic Structure Theory)

https://medium.com/@morishitter/extensible-css-idealistic-structure-theory-36bd892d3a50#.kf1mfegtj

ITCSSのアレンジ版。
違いはレイアウト専用のPageレイヤーがあることと、汎用クラスを排除している点だそうだ。

- Settings
    - (変数/設定)
- Tools
    - (mixin)
- Base
    - (normalize/reset/ベースデザイン)
- Patterns
    - オブジェクト
- Components
    - コンポーネント
- Pages
    - コンポートをレイアウトしページに配置させる

# 感想

他にもいくつかCSS設計案は見られたが、上記設計たちとほぼ違いの無い亜種ばかりでここで紹介するにも差を説明するのが難しいレベルでした。

以下をどうするかが今のCSS設計のキモかもしれない

- コンポーネントを画面上に配置する際のレイアウト調整
- mixinの利便性をとるか、設計のシンプルさをとるか
- デザインとの連携がどこまでうまくできるか