CSSアーキテクチャを導入時に必要なチームの認識あわせと、より良いCSSの実現

# はじめに
こんにちは！[ギャザリー](http://gathery.recruit-lifestyle.co.jp)で開発を担当している手塚＠inureoです。
「CSSアーキテクチャを導入する時に必要なチームの認識あわせと、より良いCSSの実現」について書かせていただきます。

# 前提
- 実際にギャザリー内で話をしていることや体験を元に書いています
- ギャザリーでは[FLOCSS](https://github.com/hiloki/flocss)を採用し、エンハンスを行いながら既存CSSのリプレイスを進めています
- フロント側に関わるチームはフロントエンドエンジニア3人、サーバサイドもできる人3人の計6人です

# CSSアーキテクチャを導入する
CSSアーキテクチャを導入する理由の多くに `メンテナブルな良いCSSを書いて運用するため` というものがあるかと思います。
僕も同じ口だったのですが、大人数で運用していく上で `メンテナブルな良いCSSを書いて運用するため` というのは少し飛躍した理由なのかなと感じてきました。正しくはメンテナブルな良いCSSを書いて運用するために `考え方のベースとして取り入れるため` なのではないかと考えています。
CSSアーキテクチャはあくまで考え方の1つでしかないのでチームの中で運用していくためには、チーム内の `メンテナブルな良いCSS` という認識を揃えなくてはなりません。認識を揃えずに運用を開始すると、チームメンバーの `メンテナブルな良いCSS` という定義がふわふわして、書くに書けない。書いたら予想と違う成果物が出てきてレビューが荒れる、などといった状況に陥ってしまうのかなと思います。
なので、CSSアーキテクチャを導入しようとする際には、ある程度チームの中で `メンテナブルな良いCSS` という認識をあわせておく必要があります。
※個人的にこの認識あわせを、チームにCSSアーキテクチャを装着すると呼んでいます。


# チームの認識をあわせよう
> チームの中で `メンテナブルな良いCSS` という認識をあわせておく必要があります。

と言いましたが、認識をあわせるとは一体なんなのか？具体的にはどういうことなのか？という話をしていきます。
結論から言ってしまうと、どういうCSSが運用しやすいのか、エンハンスしやすいのか、という認識をあわせているだけです。

一例ですが、ギャザリーでいうと下記のような部分の認識あわせをしています。

- Element名をつなげて記述しないこと
- ModifierとStateの住み分け
- 1つの要素が大きくなってきた場合にどの粒度で分解するか
- etc...

具体例として `Element名をネストしてつなげて記述しないこと` という認識を紹介しようと思います。下記のような粒度で、社内のドキュメントに追加をしていっています。

## 具体例: Element名をネストしてつなげて記述しないこと
```
良い例🙆
.recommend-article
  &__list
  	...
  &__list-item
  	...

悪い例🙅 
.recommend-article
  &__list
  	...
    &-item
  	  ...
```

### 理由としては2つ
- 悪い例の場合、直感的に理解できない
  - &-item っていうのを理解するために、親要素を辿らないといけないので直感的ではない
- 要素を検索しにくい
  - .recommend-article__list-itemを探してるのに、Element名で検索してもひっかからない


## 合意形成ではなくポリシーをもって認識をあわせること
チームの認識をあわせるということは合意形成に近いイメージですが、合意形成というよりもポリシーをもって認識をあわせることに意味があります。
例えば「クラス名の命名コストが高いなあ、取り敢えずこの名前でいいよね」のような妥協をしていくと、[割れ窓理論](http://d.hatena.ne.jp/keyword/%B3%E4%A4%EC%C1%EB%CD%FD%CF%C0)的に「こういう名前でもいいんだ」「俺も時間がないから一旦この名前で！」という風に `メンテナブルな良いCSS` の認識が甘くなっていってしまいます。曖昧な状態で命名していった要素たちは、役割が曖昧なので本来使われるべきでないところで使われ、変に拡張され影響範囲が制御できなくなり壊れやすいCSSになっていきます。
なので、自分が `絶対命名こだわるマン` になるなどポリシーをもって運用していくことが大事だと思っています。そしてポリシーなどは自分の中にとどめておかず、ドキュメントにまとめる・またはチームで議論をするなどして、チームに共有することもとても大事です。
ただし、ドキュメント管理コストが高くなったり、例外が出てきた時に崩壊しやすくなるのでバランスも大事なのが難しいところです。

このようにチームの認識あわせを行っていくと、それぞれの成果物の質も個人差が少なくなってくるはずです。

# シンプルなHTML構造と直感的なクラス名が良いCSSを実現する
チームの認識あわせの話をしてきましたが、より良い実装を行っていくのも良いCSSを実現していくために必要です。
シンプルなHTML構造は見通しがよく改修の際の事故を減らしてくれますし、直感的なクラス名は意図しない使い方・影響範囲の拡張などを防ぎ（防ぐのはレビュー時の人間ですが）、チームが変わっても学習コストが上がりにくいため保守性が向上します。

これだけだとイメージが湧きづらいと思うので、具体例をあげて説明したいと思います。

## デザインのためだけにHTMLを追加するのは避けよう
例えば見出しの頭に `☆` をつけて装飾をしたい場合にわざわざHTMLを追加して対応しなくてもいいと思います。HTMLは本来文書構造を表すものなので、装飾などはCSS側で実装してしまえばよいと思います。
※ライセンス表示などでロゴを表示する場合は、ライセンス表示自体は文書の中にあるべきなので、CSSで実装しないようにしましょう。あくまで文書構造に関係のない装飾だけです。

- 例:[https://jsfiddle.net/a7qxau8h/1/](https://jsfiddle.net/a7qxau8h/1/)


## 曖昧なクラス名をやめよう
### 例）c-heading--main, c-heading--sub
何を基準にしてメインなのか、サブなのか？メインカラムの中にあるからそうしてるのか？など直感的に理解できないので避けたいですね。また再利用も難しいと思います、再利用したら個人の感覚の違いで影響範囲が変わってしまうと思うので、壊れやすいCSSとなります。

### 例）contents, title
名前が一般的すぎるため、どういった役割なのかが見た目も影響範囲も予測しにくいです。一般的すぎる名前なので、こちらも影響範囲が制御できず意図せず見た目を壊してしまう可能性があります。

## 見た目でクラス名をつけるのはやめよう
次のように、オススメコンテンツの見出しは星の背景を敷くというスタイルがあるとします。

```
// オススメコンテンツの見出し
.c-heading--star
	@extend .heading
	background-image: url('star.png')
```

実装当初は良いのですが、デザイン変更やらで「見出しの背景画像をハートにします」とかになった場合に、見た目とクラスの不一致が起こるのでHTML側含めてクラス名を変更しなくてはいけません。
viewの中だけ検索して置き換えたが、実はJSのテンプレートの中でも使っている部分があって、変更漏れが発生した。など容易に想像ができますよね。
このように保守性が下がることがあるので、見た目で名前をつけるのではなく役割で名前をつけるようにしましょう。

# まとめ
- あくまでCSSアーキテクチャは、1つの手法・方針でしかない。ゆえに銀の弾丸ではない。
- CSSアーキテクチャはチームで解釈が変わるもの、チーム内の意識を揃えてチームに装着することが大事。
- 基本的に単純なことしか言ってないが、そもそもCSSはこわれやすいのでやりきる・守りきることが大事。妥協を許すと徐々に崩壊が始まる。
- 当たり前だが、より良い実装もメンテナブルな良いCSSにつながる。

ギャザリーもFLOCSSでのリプレイスが本格化してきたのは最近であり、これから悩んだり引っかかったりすることもあると思いますが、都度チームの認識をあわせ健全にCSSを運用していきたいと思います。