カオスになりがちなCSSともう少し向き合ってみよう

## カオスなCSSだと何がだめなのか
前回、[カオスになりがちなCSSと向き合ってみた](https://qiita.com/mde/items/4ad2a04660c2ee513c21) という投稿をしましたが、ここではダメなCSSと取り急ぎの回避策に言及しました。

実際の開発ではどうしているのか、どうすればよりベターになるのかという声がちらほら聞こえたような、そうでないような気がしたので、今回はカオスな世界から抜け出すためにやっていることを書きます。

### その前に問題を確認

1. スタイルの上書き数が多い
2. プロパティ順がぐちゃぐちゃ
3. どれを変更すれば良いかがわかりにくい

前回紹介したCSSあるあるです。これらはもっぱら複数人で作業する場合に陥りやすく、ルールがなく自由度が高くなりすぎることが主要因です。
ただ、上記3を除けば、**コードにルールを適用すれば解決する**ので、CSS整形ツールの[CSSComb](http://csscomb.com/)を使って、コード書きながら良きタイミングで整形処理を走らせたりしています。

### こんなCSSはダメだ

ツールを用いて上記1と2を解消すれば、コードに秩序がもたらされます。ただ、上記3は主にCSSのファイル管理の話となり、ここは適度にメンテナンスしなければいけません。
ファイル管理でダメな典型例をあげるとすれば、以下のような事象に遭遇したことがあります。(私が過去にやらかした事象たちです :muscle:)

- ファイル名でそのファイルの役割が判断できない

    ```sh:例1
    css/utils/modal.scss
    css/components/modal.scss
    ```
    どちらもモーダルが定義されたCSSのようですが、どう使い分けるのかがわかりません。なので、できるだけ早いタイミングで統一するか、それぞれの差異がわかるようなファイル名に変更するのがベターです。

- 同階層に重複するファイル名が存在する

    ```sh:例2
    button.scss
    btn.scss

    ui-button.scss
    ui-btn.scss
    ```
    意味の近しいファイルが複数あるパターンです。例1と同じように使い分けが難しく、作った本人が違いを説明できないという事態にもなりかねないので、分散させず1ファイルにまとめてしまいましょう。

## コードのカオス化は未然に防ごう

何度も登場している[CSSComb](http://csscomb.com/)はルールに沿って整形してくれるツールでした。
それ以外にもコードの構文チェックをしてくれるツールがあります。
人力でのチェックを最小限にするためにツールは積極的に導入し、期待した結果を得られなければ別ツールに乗り換えるのが吉です。

### Linterを使おう
JavaScriptでは[ESLint](https://github.com/eslint/eslint)という構文チェックをしてくれる Linterというツールを導入すれば、エディター上で随時エラーを検知することができます。

![eslint_sublime_linter.png](https://qiita-image-store.s3.amazonaws.com/0/53286/cbe25dff-66a6-a8de-9645-83d9a06839a2.png)


また、エラーを出すだけでなく、設定を追加すればエラーの自動修正もできるので、人的ミスの発生リスクを軽減してくれます。

CSS(SCSS)にもこのLinterがあり、私たちの開発チームでは[stylelint](https://github.com/stylelint/stylelint)を使っています。
他にも、[sass-lint](https://github.com/sasstools/sass-lint)などがありますが、GitHubのスター数はstylelintが最も多いです。

## 結局どれを使えばいいの?

**期待した結果を得られなければ別のものを使おう**という思想の下、以下の理由で私たちはstylelintを使っています。

- ESlintに近い仕様
- GitHubのスター数
- 最終更新日
- SCSSをサポートしている
    > Parses CSS-like syntaxes
    
    CSSに近しい構文であればstylelintが対応してくれ、Configファイルに [stylelint-config-recommended-scss](https://github.com/kristerkari/stylelint-config-recommended-scss) をextendすればいい感じにルールを適用してくれます。

### stylelintの設定例

実際にどんな設定をすればいいのか迷う場合は提供されているextendsを使うのが良いです。(遷移先に設定のドキュメントがあります)

- [stylelint-config-standard](https://github.com/stylelint/stylelint-config-standard)
- [stylelint-config-recommended](https://github.com/stylelint/stylelint-config-recommended)

で、前回に続き、私たちの設定を晒します。もう怖いものはありません。

```yaml:.stylelintrc.yml
---
extends: stylelint-config-recommended-scss
rules:
  indentation: 2 # インデントはスペース2つにする
  string-quotes: double # ダブルクオートを使う(シングルクオートはだめ)
  no-duplicate-selectors: true # ファイル内の同じ階層に同セレクタを2回書かない
  color-hex-case: lower # `#ffffff`のように小文字にする
  color-hex-length: short # 可能は限り `#fff` ショートハンドで書く
  color-named: never # `color: black;` などの色名指定をしない
  selector-combinator-space-after: always
  selector-attribute-quotes: always # 属性セレクタは `"attr"` のようにする
  selector-attribute-operator-space-before: always
  selector-attribute-operator-space-after: always
  selector-attribute-brackets-space-inside: never
  declaration-block-trailing-semicolon: always # 末尾のセミコロンは必須
  declaration-colon-space-before: never # プロパティ名とコロンの間にスペース入れない
  declaration-colon-space-after: always-single-line # コロンの後はが1行ならスペース入れる
  property-no-vendor-prefix: true #  Autoprefixerを使う ので`vendor-prefix`は書かない
  number-leading-zero: never # `0.5`を`.5`のように`0`を省略する
  font-weight-notation: numeric # `font-weight: 700`のように数字を使う
  comment-empty-line-before: always # コメントの前に空行
  rule-empty-line-before:
    - always-multi-line
    - ignore:
      - after-comment # コメント後に空行入れない
      - inside-block # ブロック内であれば空行なくてもよい
  selector-pseudo-element-colon-notation: single # セレクタは1行に並べる
  selector-pseudo-class-parentheses-space-inside: never # カッコ内に空白入れない
  media-feature-range-operator-space-before: always # メディアクエリの範囲演算子の前に空白入れる
  media-feature-range-operator-space-after: always # メディアクエリの範囲演算子の後ろに空白入れる
  media-feature-parentheses-space-inside: never # メディアクエリの範囲を指定するカッコに空白入れない
  media-feature-colon-space-before: never # コロン前にスペース入れない
  media-feature-colon-space-after: always # コロン後ろにスペース入れる

```

## おまけ(それでも漏れちゃう場合)

### 記述ミスを最小限にしよう

コードを書く絶対量を減らして、ミスを軽減しようという企画です。つまり、**独力で書かない**ということです。

![emmet.gif](https://qiita-image-store.s3.amazonaws.com/0/53286/9c69c8fe-fd58-c68a-927e-b8ec03b9ebfb.gif)

これは、[emmet](https://emmet.io/)というプラグインを使用して楽をしている図です。
私の場合はSublime Textにemmetを導入しているおかげで、 `d-f` とタイプすれば `display: flex;` となるように、追加したいプロパティの冒頭を入力すれば候補を返してくれます。
「こういうの使うと正しいプロパティを忘れてしまう」という人がいましたが、そういう人はそもそも正しく覚えていないので、気にせず積極的に使いましょう。

### 自動レビューツールで構文エラーの見逃しを無くそう

私たちのチームでは[Codacy](https://www.codacy.com/)というコード分析ツールを使っています。

![codacy.png](https://qiita-image-store.s3.amazonaws.com/0/53286/7a53c4a8-f0bb-46ef-f6ec-1e81f6f60bef.png)

健康なコードを書いてPull Requestを出すと **Good Work!!** と褒められます。
逆に悪いコードを書くと、**Not so good...** と怒られ、修正レビューを出されます。

![codacy_not_so_good.png](https://qiita-image-store.s3.amazonaws.com/0/53286/4ae55694-4104-f675-3165-f4fcb7d83518.png)

Githubでは以下のようなエラーがでます :crying_cat_face:

<img width="770" alt="codacy_github.png" src="https://qiita-image-store.s3.amazonaws.com/0/53286/10c28212-f4d7-db0f-07c4-de5073bb0a09.png">

この判定はこれまでに紹介した構文チェックルールと連動できるので、レビュー体制のある開発チームにおいては不要なレビューを減らすことができます。

---

[前回](https://qiita.com/mde/items/4ad2a04660c2ee513c21)に引き続き、カオスなCSSに少しでも秩序をという想いでここまで書いてきました。

[Codacy](https://www.codacy.com/)について最後に触れましたが、PRに対して **Good Work!** と言われるのは、嬉しいものがあります。
仮に Not so good でもレビュー依頼を出す前の指摘してくれるので、無駄の回避に繋がります。
より良いベストプラクティスが今後もっと出てくるかもしれませんが、積極的に活用して常に秩序あるCSSを、極力楽して書きたいですね！