ITCSSまとめ

[ITCSS](http://itcss.io/)は、[OOCSS](http://oocss.org/)や[BEM](http://getbem.com/introduction/)、[SMACSS](https://smacss.com/)のようなCSS methodology(方法論)の１つで*Inverted Triangle CSS*(逆三角形CSS)の略称。
提唱したのは、[csswizardry](http://csswizardry.com/)のHarry Roberts氏。
ITCSSに関するドキュメントはあまり多くない。
セルビアでITCSSについて紹介している[動画](https://www.youtube.com/watch?v=1OKZOV-iLj4)がYoutubeにあがってる。そのときのスライドが[Managing CSS Projects with ITCSS // Speaker Deck](https://speakerdeck.com/dafed/managing-css-projects-with-itcss)。

ITCSSは、プロジェクトのCSSをより良く管理していくのに、以下のことが必要としていて、

> - A **sane environment** that is accessible to lots of people. 
> - To **tame and manage** source order and the cascade. 
> - To create **a place for everything** to live (new and old). 
> - To **reduce** waste and redundancy. 
> - To **end the Specificity Wars**.
> 
> https://speakerdeck.com/dafed/managing-css-projects-with-itcss

内容としては大体こういうことだと思われる。

- 多くの人にとって理解しやすい健全な環境
- 記述順とカスケードを管理すること
- 新旧問わず全てのルールセットが生きられる場所をつくること
- 無駄と重複を減らすこと
- 詳細度の戦いを終わらせること


その上でITCSSは、
> **Manages** source order. 
> Filters **explicitness**. 
> **Tames** the cascade. 
> **Sanitises** inheritance.
> 
> https://speakerdeck.com/dafed/managing-css-projects-with-itcss

- 記述順を管理する
- 明示性をフィルター？
- カスケードを飼いならす
- 継承を安全にする

大体こんな感じの方向性になる。


## Specificity Graph

CSSを記述する上で重要になる詳細度。
CSSを詳細度を考えずに書いていけば、そのうち`!important`で上書きするなど、既存のルールセットに苦しむことになりやすい。

[Specificity Graph](https://github.com/pocketjoso/specificity-graph)はCSSの詳細度と記述場所をグラフ化してくれるツール。
右肩上がりのグラフになることが望ましいとされていて、ジグザグのグラフになれば詳細度の問題が起きやすいということがわかる。

ITCSSの場合、この詳細度順に記述することになるので、右肩上がりのグラフになりやすい。
このグラフを右肩上がりに保ち続けることが、CSSを健全な状態に保っていることの指標になるということ。


## レイヤー

ITCSSでは以下のレイヤーに分けてCSSを構成する。

| Layer | 役割 |
| ------ | ------- |
| Settings | プリプロセッサで利用するグローバル変数や全体の設定 |
| Tools | プリプロセッサで利用するmixinやfunctionなど |
| Generic | normalize.css、reset |
| Base | 要素型セレクタ |
| Objects | 装飾を持たないデザインパターン |
| Components | コンポーネント |
| Trumps | ヘルパー。`!important`を利用していい |

![itcss.png](https://qiita-image-store.s3.amazonaws.com/0/11465/01acec10-0372-1c00-a2e6-47d8ca0667f5.png)

- レイヤーが下に行くほど詳細度が徐々に高くなっていく。
- レイヤーが下に行くほど汎用的ではなく明示的になる。
- レイヤーが下に行くほど局地的になる。

ITCSSはこのレイヤーを増減してスケールできるとしていて、

> Add or remove layers if, as, and **when you need to**. 
> Not using a preprocessor? **Remove** the Settings and Tools layers. 
> Don’t use OOCSS? **Remove** the Objects layer. 
> Need theming? Add a **Theme layer**.
> 
> Booking.com run a lot of **A/B tests**. 
> How do we **isolate temporary styles**? 
> Create a **Test layer** (before the Trumps layer).
> 
> https://speakerdeck.com/dafed/managing-css-projects-with-itcss

- OOCSSじゃない
    - **Objects**レイヤーを削除すればいい
- プリプロセッサを使わない
    - **Tools**と**Settings**を削除すればいい
- テーマが必要
    - **Themes**レイヤーを**Components**レイヤーの下に追加すればいい
- A/Bテスト用のクラスが必要
    - **Test**レイヤーを**Trumps**レイヤーの上に追加すればいい

としている。

ITCSSの具体例は[githubで探せば数は多くないけど、見つかることは見つかる](https://github.com/search?l=CSS&q=itcss&type=Repositories&utf8=%E2%9C%93)。



## 各レイヤーの内容

### Settings

プリプロセッサの設定、グローバル変数。
プロジェクト全体で利用するようなものを**settings**レイヤーにまとめる。

```scss
$color-primary: #333;
$color-secondary: #666;
```

### Tools

**Settings**レイヤーと同じようにプリプロセッサ用のレイヤー。
プリプロセッサ用のmixinやfunctionをこのレイヤーで管理する。

```scss
@mixin some-mixin () {
  ...
}
```
ここまでのレイヤーは、CSSに直接出力されることのないもので記述されてる。

### Generic

このレイヤーからプリプロセッサ用ではなくCSS用のレイヤーになる。
reset、normalizeなど。全ての出発点となるスタイルを持つレイヤー。

```scss
* {
  box-sizing: border-box;

  &:before,
  &:after {
    box-sizing: border-box;
  }
}
```

### Base

[要素型セレクタ](https://developer.mozilla.org/ja/docs/Web/CSS/Type_selectors)のルールセットをまとめるレイヤー。

```scss
p {
  margin: 0;
}
```

このレイヤー以降、要素型セレクタは記述しない。

### Objects

OOCSSのレイヤー。装飾のスタイルを持たないデザインパターンをこのレイヤーにまとめる。
レイアウト目的のスタイルをこのレイヤーに持たせるのが正しいのかもしれない。
次に来る**Components**レイヤーとの境界線の判断が難しそう。

クラスセレクタはこのレイヤーから使う。明示的なクラス名は避ける。

```scss
.o-card {
  display: table;
  table-layout: fixed;
  width: 100%;
  
  &__head {
     ..
  }
}
```

### Components

装飾のスタイルを持つUIパーツ。
このレイヤーでもクラスセレクタを使う。**Objects**レイヤーよりも明示的なクラス名をつける。

```scss
.c-button {
  display: block;
  background-color: #333;
  color: #fff;
  ...
}
```
```scss
.c-profile-title {
  display: block;
  background-color: rgba(0, 0, 0, 0.7);
  ...
}
```

### Trumps

ヘルパー、ユーティリティ。
上位レイヤーのスタイルを上書きすることが目的になって、`!important;`を記述していいレイヤー。
１つのHTML要素だけに影響するルールセットを記述する。

```scss
.u-hidden {
  display: hidden !important;
}
```


## ディレクトリ構成

ITCSSでは全てのパーシャルファイルを１つのディレクトリにフラットに配置するのが推奨されているっぽい。

https://github.com/itcss/itcss-netmag/tree/master/css

各パーシャルファイルの先頭に、属するレイヤー名をつける形をとる。
これをレイヤー順に`import`することで、ITCSSの方法論に従ったCSSということになる。

```scss
@import "settings.global";
...

@import "tools.mixins";
...

@import "generic.normalize";
@import "generic.reset";
...

@import "base.body";
@import "base.list";
@import "base.headings";
...

@import "objects.wrapper";
@import "objects.sidebar";
@import "objects.header";
@import "objects.footer";
...

@import "components.badge";
@import "components.button";
@import "components.carousel";
@import "components.thumbnail";
...

@import "trumps.width";
@import "trumps.display";
...

```



## Links

- [Managing CSS Projects with ITCSS // Speaker Deck](https://speakerdeck.com/dafed/managing-css-projects-with-itcss)
- [ITCSS: Scalable and Maintainable CSS Architecture - Xfive](https://www.xfive.co/blog/itcss-scalable-maintainable-css-architecture/)
- [How I Shrank my CSS by 84kb by Refactoring with ITCSS — Medium](https://medium.com/@jordankoschei/how-i-shrank-my-css-by-84kb-by-refactoring-with-itcss-2e8dafee123a#.901o4jivx)
- [itcss/itcss-netmag](https://github.com/itcss/itcss-netmag)