2留でも書けるCSSコーディング規約

## 🔰 はじめに
### 📝 背景
CSSは記述ルールが簡潔であり、誰でも簡単に少ない学習コストで利用できるツールです。一方で誰でも書けてしまうが故に複数人での開発では、各人が自身のオリジナルルールに則ったコーディングをしてしまいがちです。それらの問題を解消すべく、コーディングルールを作成する事に至りました。

### 📝 目的
1. クオリティの均一化
    * コーダーによる精度のバラつきを防ぐ
2. 制作効率の向上
    * コーディングの際の「迷い」を解消する
3. メンテナンスコストを削減
    * 修正やチェック等の、メンテナンスの工数を減らす


### 📝 いいCSSのゴールとは
Googleのデベロッパーである[Philip Walton](https://philipwalton.com)氏は[CSS Architecture](https://philipwalton.com/articles/css-architecture/)にていいCSSとは、下記の4点が押さえられている物だと述べています。

* 予測しやすい
* 再利用しやすい
* 保守しやすい
* 拡張しやすい

ここ数年は下記のような信念を元に開発が進められていますが、まさにPhilip Walton氏が述べる4つの理念と一致しています。

1. セマンティック
	* 見た目ではなく、目的や役割を元に命名をすることで **予測** しやすくする
2. DRY
	* "Don't repeat yourself" 繰り返し同じコードを書くのではなく、 **再利用性** を高める
3. メンテナブル
	* レイアウト間でのcssの依存関係を減らし、他のパーツへの影響を及ぼさない **保守** を可能とする
4. スケーラブル
	* コードの記法を一貫させることで **拡張性** を高める

今回はこれらの4点の実現を目指すべく、コーディングルールを制定しました。

### 📝 規約を読む前に
これから列挙するコーディング規約は必ずしもベストプラクティスであるとは限りません。ベストプラクティスとは、それぞれのチーム毎に、そして案件毎に変わるものであるからです。開発を開始する前にチームで「このルールは採用しよう」「このルールはここを変えて使おう」といったディスカッションをしていただければと思います。大切なのはベストプラクティスを模索する事ももちろんですが、チームで話し合いの場を設け、コーディングルールに関しての認識をメンバー同士ですり合わせる事で共通の認識を得る事であると考えています。  
また、今回はなるべくFLOCSS、BEM、SCSS等を使用する環境でなくてもルールを導入できるように考慮して記事を執筆しました。CSSを最近書き始めた方も是非読んで参考にしていただければと思います。

### 📝 cssを構成しているパーツ名称
![ruleSet.png](https://qiita-image-store.s3.amazonaws.com/0/48027/f51d5daa-f535-cc54-5314-7e51fdc3cb98.png)


## 🎁 スタイル編
### 💎 インデント
全ファイルにて共通のインデントを取る。スペース2個が望ましい。

``` css:NG
.element {
   color: red;
 background-color: blue;
}
```
``` css:OK
.element {
  color: red;
  background-color: blue;
}
```
```text:Why?
可読性向上の為
```
**別の選択肢**

* スペース4個
* ハードタブ


### 💎 ルールセット間の改行
ルールセット同士の間にはスペースを設けます。

``` css:NG
.danger {
  color: #d9534f;
}
.success {
  color: #5cb85c;
}
```
``` css:OK
.danger {
  color: #d9534f;
}

.success {
  color: #5cb85c;
}
```
```text:Why?
可読性向上の為
```


### 💎 ルールセットにタイトルを付ける
どんな機能なのかを、タイトルで示します。

``` css:NG
.danger {
  color: #d9534f;
}
```
``` css:OK
/* Text color Danger */
.danger {
  color: #d9534f;
}
```
```text:Why?
可読性向上の為
```


### 💎 ルールセット内のスペース
セレクタと`{`の間、プロパティの後の`:`とバリューの間にはスペースを入れます。

``` css:NG
.element{
  color:red;
}
```
``` css:OK
.element {
  color: red;
}
```
```text:Why?
可読性向上の為
```


### 💎 ルールセット内の改行
ルールセット内に複数のセレクタや宣言を記述すときは1行に記述せず、改行して複数行に記述します。

``` css:NG
.btn, .link {
  color: red; font-size: 1.5rem;
}
```
``` css:OK
.btn,
.link {
  color: red;
  font-size: 1.5rem;
}
```
```text:Why?
可読性向上の為
```


### 💎 宣言後のセミコロンを付ける
バリューの後の`;`は宣言同士を区切るための物なので最後の宣言には付けなくても問題はありません。しかし、宣言を更に追加する際のメンテナンスに支障をきたすので全ての宣言に対してセミコロンを付けます。

``` css:NG
.element {
  color: red;
  font-size: 1.5rem
}
```
``` css:OK
.element {
  color: red;
  font-size: 1.5rem;
}
```
```text:Why?
メンテナンス性向上の為
```


## 🎁 セレクタ編
### 💎 命名を簡略化する
セレクタの名前は可能な限り簡略化します。しかし、意味がわからなくなるような簡略化は可読性の悪化に著しく影響を及ぼすので避けます。

``` css:NG
.information {
  color: red;
}

.cat {
  color: blue;
}

.bc {
  color: green;
}
```
``` css:OK
.info {
  color: red;
}

.category {
  color: blue;
}

.breadCrumb {
  color: green;
}
```
```text:Why?
可読性向上の為
```


### 💎 絶対値を表す命名を避ける
セレクタ名とバリューの値の関係性を強めてしまうような命名は避けます。そのような命名は可読性の向上に繋がりますが、値を変更した際にセレクタの命名も同時に変更する必要が出てきてしまいます。

``` css:NG
.red {
  color: red;
}

.btn100 {
  width: 100px;
}
```
``` css:OK
.danger {
  color: red;
}

.btnShort {
  width: 100px;
}
```
```text:Why?
メンテナンス性向上の為
```


### 💎 強い意味を持つ命名を避ける
絶対値を表す命名と同じように、モジュールについての説明的な意味合いを持つ命名も避けます。パーツは常に汎用性を持たせることを意識して命名をします。

``` css:NG
/* バラク・オバマの説明にしか使えない */
.AboutBarackObama {
  background-color: #ccc;
}
```
``` css:OK
/* いろいろな人の説明に使える */
.profile {
  background-color: #ccc;
}
```
```text:Why?
再利用性向上の為
```


### 💎 HTMLタグと同じ単語を含む命名を避ける
`span`や`img`等のHTMLタグと同じ単語をセレクタ名として使用することはルールセットがHTML構造に依存的になってしまうので避けます。また、ファイル内語句検索の際に支障を与えてしまうことも一つの理由です。

``` css:NG
.article {
  color: red;
}
.logoImg {
  border: 1px solid #ddd;
}
```
``` css:OK
.post {
  color: red;
}
.logoImage {
  border: 1px solid #ddd;
}
```
```text:Why?
検索機能、再利用性向上の為
```


### 💎 2語以上ではキャメルケース表記
2語以上単語が続くときは、2語目以降の単語の1文字目は大文字(キャメルケース)で記述します。

``` css:NG
.content_area {
  background-color: #ccc;
}

```
``` css:OK
.contentArea {
  background-color: #ccc;
}
```
```text:Why?
可読性向上の為
```

**別の選択肢**

* チェインケース(ハイフン)
* スネークケース(アンダースコア) (BEMには向かない)


### 💎 IDセレクタでのスタイル指定を避ける
IDセレクタはクラスセレクタと違い、ページ内で1回しか使用する事ができません。再利用できないルールセットを記述することは再利用性の向上という理念から大きく外れることになります。また、IDセレクタはクラスセレクタと比べ、詳細度が高くなるので意図せぬ挙動を引き起こす可能性があります。これらの観点より、IDセレクタの使用は基本的に禁止とします。

``` css:NG
#element {
  color: red;
}

```
``` css:OK
.element {
  color: red;
}
```
```text:Why?
再利用性の欠如、詳細度の複雑化
```


### 💎 クラスセレクタにタイプセレクタを付与しない
タイプセレクタを使用することでルールセットがHTML構造に依存してしまう為、`h2`等の別のタグにて使用する事ができません。あえて詳細度を高め、再利用性を低下させる必要はありません。

``` css:NG
h1.element {
  color: red;
}

```
``` css:OK
.element {
  color: red;
}
```
```text:Why?
再利用性向上の為
```


### 💎 タイプセレクタの使用を極力避ける
タイプセレクタを使用することでルールセットがHTML構造に依存してしまう為、`h2`等の別のタグにて使用する事ができません。再利用性を高める為にクラスセレクタを使用してスタイル指定をします。

``` css:NG
.element h1{
  color: red;
}

```
``` css:OK
.element .elementTitle {
  color: red;
}
```
```text:Why?
再利用性向上の為
```


### 💎 ユニバーサルセレクタを使用しない
ユニバーサルセレクタには詳細度が無い為、予期せぬ挙動を引き起こす可能性があります。リセットcss以外への使用は基本的に禁止とします。

``` css:NG
* {
  color: #999;
}

```
``` css:OK
html,
body {
  color: #999;
}
```
```text:Why?
メンテナンス性向上の為
```


## 🎁 プロパティ編
### 💎 プロパティを同じ順番で並べる
1. 位置情報系(position, top, right, z-index, display, float等)
2. サイズ(width, height, padding, margin)
3. 背景(background, border等)
4. 文字系(font, line-height, letter-spacing, color- text-align等)
5. その他(animation, transition等)

``` css:NG
.element {
  text-align: center;
  width: 100px;
  background-color: #ddd;
  position: relative;
  margin: 10px;
}

```
``` css:OK
.element {
  position: relative;
  width: 100px;
  margin: 10px;
  background-color: #ddd;
  text-align: center;
}
```
```text:Why?
メンテナンス性、可読性向上の為
```
**別の選択肢**

* アルファベット順


### 💎 ショートハンドプロパティを使用
`border`, `margin`等のプロパティでは可能な限りショートハンドを使って簡潔にルールセットをします。

```css:NG
.element {
  padding-left: 5px;  
  padding-top: 10px;  
  padding-right: 5px;
  padding-bottom: 15px; 
}
```
```css:OK
.element {
  padding: 10px 5px 15px 5px; 
}

/* 更に省略できる */
.element {
  padding: 10px 5px 15px;
}
```
```text:Why?
ファイルサイズ削減、メンテナンス性、可読性向上の為
```


## 🎁 バリュー
### 💎 小数は小数部のみを表記
値が0以下の少数の場合は0を省略し、小数点及び小数部のみを記述します。

```css:NG
.element {
  font-size: 0.8em;
}
```
```css:OK
.element {
  font-size: .8em;
}
```
```text:Why?
ファイルサイズ削減の為
```


### 💎 0には単位を付けない
値が0の場合は`px`, `rem`等の単位を省略し、0のみを記述します。

```css:NG
.element {
  margin: 0px 10px;
}
```
```css:OK
.element {
  margin: 0 10px;
}
```
```text:Why?
ファイルサイズ削減の為
```


### 💎 色は16進数で表記
バリューにカラーを指定する場合は16進数形式で記述します。

```css:NG
.element {
  color: rgba(255,255,255);
}
```
```css:OK
.element {
  color: #000;
}

/* rgba表記(SCSS) */
.element {
  color: rgba(#000, .8);
}
```
```text:Why?
ファイルサイズ削減、メンテナンス性、可読性向上の為
```



### 💎 可能なときはカラーコードを省略
16進数表記のカラーコードは、可能な限り3桁で記述します。

```css:NG
.element {
  color: #ffffff;
}
```
```css:OK
.element {
  color: #fff;
}
```
```text:Why?
ファイルサイズ削減の為
```


## 🎁 その他
### 💎 小文字のみ
プロパティやバリューは大文字で記述しても機能上の問題はありませんが、スタイルを統一する為に全て小文字で記述します。(キャメルケース使用時等の例外を除く)

```css:NG
.element {
  BackGround-Color: #AAA;
}
```
```css:OK
.element {
  background-color: #aaa;
}
```
```text:Why?
スタイル統一の為
```


### 💎 !importantの使用を避ける
詳細度を急激に高めてしまうので基本的には使用しませんが、多重継承されているスタイルの打ち消し等、場合によっては使用します。`!important`を使用する場面に遭遇したときは、CSS構造が複雑になっている可能性があるので、CSSを見直します。

```css:NG
.element {
  width: 100px !important;
}
```

```text:Why?
メンテナンス性向上の為
```


### 💎 メディアクエリ内での複数のモジュール指定を避ける
メディアクエリ内に複数のルールセットを記述することは、モジュールベースでの開発を著しく阻害します。メンテナンス性向上の為、モジュール毎に、更に言うとモジュールの中でメディアクエリを用意します。

```css:NG
.aleartModule {
  width: 1060px;
  color: #d9534f;
}

.successModule {
  width: 660px;
  color: #4cae4c;
}

.infoModule {
  width: 860px;
  color: #46b8da;
}

@media screen and (max-width: 999px) {
  .aleartModule {
    width: 100%;
  }

  .successModule {
    width: 60%;
  }

  .infoModule {
    width: 80%;
  }
}
```
```css:OK
.aleartModule {
  width: 1060px;
  color: #d9534f;
}
@media screen and (max-width: 999px) {
  .aleartModule {
    width: 100%;
  }
}

.successModule {
  width: 660px;
  color: #4cae4c;
}
@media screen and (max-width: 999px) {
  .successModule {
    width: 60%;
  }
}

.infoModule {
  width: 860px;
  color: #46b8da;
}
@media screen and (max-width: 999px) {
  .infoModule {
    width: 80%;
  }
}
```
```scss:scssで書くと...
.aleartModule {
  width: 1060px;
  color: #d9534f;
  @media screen and (max-width: 999px) {
    width: 100%;
  }
}
.successModule {
  width: 660px;
  color: #4cae4c;
  @media screen and (max-width: 999px) {
    width: 60%;
  }
}
.infoModule {
  width: 860px;
  color: #46b8da;
  @media screen and (max-width: 999px) {
    width: 80%;
  }
}
```
```text:Why?
メンテナンス性向上の為
```


### 💎 汎用ルールの使用を避ける
汎用ルールは手軽に宣言を適応できる便利なアイディアですが、メンテナンス性を考慮するとインラインスタイルでの宣言とやっている事は何ら変わりがありません。使用はなるべく避け、レイアウト部やモジュール部の変更で対応できないかを検討します。

```html:NG
<p class="mb10">テキスト</p>
```
```css:NG
.mb10 {
  margin-bottom: 10px;
}
```

```text:Why?
メンテナンス性向上の為
```


### 💎 打ち消しをするルールを書かない
打ち消しをするCSSよりも、宣言を追加して目的のレイアウトを再現するCSSの方が全体的な宣言の数が少なく済みます。

```html:HTML
<h1 class="element">タイトル</h1>
```
```css:NG
h1 {
  margin: 5px 0 10px;
  padding: 5px 10px;
  background-color: #eee;
  border: 1px solid #222;
  color: red;
}
.element {
  background-color: none;
  border: none;
}
```
```css:OK
h1 {
  margin: 5px 0 10px;
  padding: 5px 10px;
  color: red;
}
.element {
  background-color: #eee;
  border: 1px solid #222;
}
```
```text:Why?
データサイズ削減、メンテナンス性、再利用性向上の為
```


### 💎 タイプセレクタには装飾的プロパティを書かない
`h1`や`p`等のセマンティックなタイプセレクタへの装飾的プロパティの使用は打ち消しするCSSの記述を助長させる要因となるので避けます。

```html:HTML
<h1 class="title">タイトル</h1>
```
```css:NG
h1 {
  background-color: #eee;
  border: 1px solid #222;
  color: red;
}
```
```css:OK
.title {
  background-color: #eee;
  border: 1px solid #222;
  color: red;
}
```
```text:Why?
メンテナンス性、再利用性向上の為
```


### 💎 状態を表すルールセットには`is-`プレフィックスを付ける
状態を表す(別パターン)のデザイン、BEMで言う所のModifierに相当する部分には接頭辞として`is-`を付けます。javascriptを使用する際の`js-`プレフィックスの記述方法と統一することで可読性の向上に一層繋がります。

```css:NG
.colorDanger {
  color: #d9534f;
}
```
```css:OK
.is-colorDanger {
  color: #d9534f;
}
```
```text:Why?
可読性、再利用性向上の為
```


### 💎 BEMを使用する
セレクタの命名を統一する方法の一つとしてBEM(MindBEMding)という規則がある。要素をBlock, Element, Modifierに分けて命名するのが特徴。

```html:NG
<ul class="content">
  <li>テキスト</li>
  <li>テキスト</li>
  <li class="colorDanger">赤文字テキスト</li>
  <li>テキスト</li>
</ul>
```
```css:NG
.content {
  background-color: #bbb;
}

li {
  border: 1px solid #000;
}

li.colorRed {
  color: #d9534f;
}
```
```html:OK
<ul class="contentList">
  <li class="contentList__element">テキスト</li>
  <li class="contentList__element">テキスト</li>
  <li class="contentList__element　is-colorDanger">赤文字テキスト</li>
  <li class="contentList__element">テキスト</li>
</ul>
```
```css:OK
.contentList {
  background-color: #bbb;
}

.contentList .contentList__element {
  border: 1px solid #000;
}

.contentList .contentList__element.is_colorDanger {
  color: #d9534f;
}
```
```scss:scssで書くと...
.contentList {
  background-color: #bbb;
  & &__element {
    border: 1px solid #000;
    &.is_colorDanger {
      color: #d9534f;
    }
  }
}
```
```text:Why?
メンテナンス性、可読性の向上
```
**BEMに関しての詳しい概要は下記リンクから**

* [BEMによるフロントエンドの設計](https://app.codegrid.net/entry/bem-basic-1)
* [BEMという命名規則とSass 3.3の新しい記法](http://blog.ruedap.com/2013/10/29/block-element-modifier)


### 💎 モジュールの上下左右にはマージンを取らない
モジュールは再利用する為に存在するルールセットですが、再利用先で既にルールセットに記述した`margin`の値と異なる余白を取りたいときには打ち消しをするCSSを記述する必要が出てきます。これは再利用性を著しく阻害するので避けます。

```css:NG
.moduleBlock {
  margin: 15px 10px 30px;
  background-color: #999;
}
```
```css:OK
.moduleBlock {

  background-color: #999;
}
```
```text:Why?
再利用性向上の為
```


### 💎 コンテンツ間の余白の取り方を統一
コンテンツ間の余白を取る為のプロパティ使用時は上部で余白を取るか下部で余白を取るか統一します。余白の相殺や予期せぬ挙動を防ぐ為です。コンテンツ間の余白を取る為のルールセットを用意するのも一つの手段です。

```css:NG
.aboutBlock {
  margin-top: 30px;
}
.careerBlock {
  margin-bottom: 30px;
}
.contactBlock {
  margin-top: 30px;
}
```
```css:OK
.aboutBlock {
  margin-bottom: 30px;
}
.careerBlock {
  margin-bottom: 30px;
}
.contactBlock {
  margin-bottom: 30px;
}
```
```text:Why?
可読性、メンテナンス性向上の為
```


### 💎 コメントスタイル
コメントアウトには単行と複行と言った種類があります。コンパイルされるか否かを踏まえた上でどちらをどのようなルールで使用するか検討します。

```css:css
  // このコメントはscssでコンパイルされない
  /* このコメントはscssでコンパイルされる */
```


## 📚 参考
上記のルールは下記のリファレンスを元に作成致しました。どれも素晴らしい内容となっておりますので、是非一読していただければと思います。
- [Web制作者のためのCSS設計の教科書](https://www.amazon.co.jp/dp/4844336355/ref=cm_sw_r_tw_dp_k9Bwxb3R0P1G9)
- [メンテナブルCSS - 株式会社サイバーエージェント](https://www.cyberagent.co.jp/techinfo/techreport/report/id=7926)
- [こんなHTMLとCSSのコーディング規約で書きたい - Qiita](http://qiita.com/pugiemonn/items/964203782e1fcb3d02c3)
- [CSS Architecture (和訳)](http://article.enja.io/articles/css-architecture.html)