【初心者向け】CSSを綺麗に書くために決めている基本ルール


## CSSは綺麗に書きたいですよね。
BEM、SMACCSS、CSS設計、詳細度。色々覚えたけどどうもCSSが汚くてなんとなく見にくいと思ってる人もいるかもしれません。
なので、今回は見やすいCSSを書くために僕が決めている基本ルールを書きます。

## どんどんアップデートしていく予定です。
色々自分の中で決めているマイルールのようなものはたくさんあるのですが、まだ全て洗い出せていないのでひとまず公開。まとめて書くと一生公開できなさそうなので…。
随時更新していく予定です。
HTML/CSSのコーディング規約も書いていきたいです。(別の記事かもしれませんが・・)

それではこれより下からスタートです。

## プロパティはアルファベット順に書く


プロパティは、下のようにアルファベットの順をバラバラに書くのではなく、

```css
.hogehoge {
	color: red;
	background-color: blue;
}
```

```css
.hogehoge {
	background-color: blue; / * abc順に */
	color: red;
}
```

とする。
extendやmixinは状況次第で臨機応変に対応するが、基本的にプロパティの一番最後に書く。
paddingやmarginは、ショートハンドを使う。
上書きしたいなど何かしら使えない理由がある場合は、 **上右下左** の時計周りで記述する。(ここはabc順無視)

```css
.hogehoge {
	padding-top: 10px;
	padding-right: 20px;
	padding-bottom: 8px;
	padding-left: 15px;
}
```

またSCSSなら

```scss
.hogehoge {
  padding: {
    top: 10px;
    right: 20px;
    bottom: 8px;
    left: 15px;
  }
}
```
のように書ける。

## プロパティとバリューの間は空ける
```
.hogehoge {
  color: red;
}
```

のように、コロンとバリューの間は空けるようにする。

## まとめられるものはまとめて書く。(Sass/SCSS)

上とも関連するが、SCSSを使える時はfont/border/paddingなどは共通化して書く。ここでいう共通化というのはショートハンドのことではなく

```
.hogehoge {
  border: 1px solid red {
    radius: 5px;
  }
  font: {
    size: 16px;
    weight: bold;
  }
}

```

のような書き方のこと。構造化して見やすくなるのと無駄に記述するのを省ける。

参考： http://book.scss.jp/code/c3/03.html


## SCSSではなくSassを使う
SCSSなら

```scss
.hogehoge {
	color: red;
	border: 1px solid #ccc;
}
```
と書けばある程度綺麗だが、極端な話、

```scss
.hogehoge {
	color:red;
border:1px solid #ccc;
}
```
このような **インデントがバラバラだったりコロンのあとにスペースがなかったりする**状態でも特にエラーが出ないで可読性が悪くなる。

これを解決するために上のようなルールを適用してもいいが、セミコロンをいちいち最後に書くとか、{}で書くのは面倒なのでSass記法を使うのがよい。

```sass
.hogehoge
  color: red
  border: 1px solid #ccc
```

のようにSassを書くと

- {}がいらないかわりにインデントで記述
- セミコロンがいらない
- **コロンのあとのスペースが空いていないとエラーが出るので自然と誰が書いても綺麗なコードに**

というメリットがある。
mixinの文法が少しだけ異なったりと、若干SCSSとは違うがそこまで大きく違うわけではないので、学習コストも最小限にSCSSから切り替えられるだろう。
特に普段からRails使ってビューも書いているような人はすぐ馴染めると思う。

詳細は [Sass公式のLEARN SASS](http://sass-lang.com/guide)を参照。

## BEMやSMACCSを導入して綺麗に書く。

BEMを使うとCSSの命名がある程度シンプルになり、SMACCSを使うとCSSのファイル分けが分かりやすくなるというメリットがある。
他にもFLOCSSなど様々あるので、使いやすいものをチョイスしてプロジェクトに組み込むのが良い。
SMACSSでmoduleごとにファイルを分けたら、

なおBEMには下記のような問題がある。

```sass
.block
  .block__element
    .block__element__element2
```

と、どんどん入れ子になってしまったり、

```sass
.block

.block__element

.block__element__element2
```

入れ子にしたくない(セレクタの優先順位のため)からわざわざ分けて書いたり、

とBEMを使うとBEM特有の問題が発生する。

前者はセレクタの優先順位の問題、後者はどこまでがそのblockの仕事かが分かりにくくなる、というデメリットがある。

後者については、コメントアウトを入れるなどして対応することも可能だがもっとシンプルにやる方法がほしい。

そこでBEMを使うときは以下のmixinを書いておくと良い。

```sass
// BEM -Element
=e($name)
  @at-root #{&}__#{$name}
    @content
    
// BEM - Modifier
=m($name)
  @at-root #{&}--#{$name}
    @content
```

これを使うと

```sass
.block
  +e(element) // 引数にelementの名前を指定
    +e(element2)
```

とすると、CSSでの出力結果では、

```css
.block {}
.block__element {}
.block__element__element2 {}
```

となり上の問題を解決することができるので是非使用をおすすめしたい。

**※追記**

コメントでご指摘受けましたが

Sass3.3からは

```sass
.block
  &__element
    &__element2
      ...
```

と記述しても

```css
.block {}
.block__element {}
.block__element__element2 {}
```

のように出力されます。

また[BEMをSassで快適に書く方法](http://mae.chab.in/archives/2553#post2553-4)が参考になりました。

@ShinyaNatsumi さんご指摘ありがとうございました！


## idは使わずclassを使う
idは固有のもの、classは複数で適用させたいもの、とはじめに教わったかもしれないが、個人的にはidを使う理由がない。
理由は、

- idでできることはclassでもできる
- idを使うとセレクタの優先順位が上がる
- idはJSで使いたい

二番目の問題は、[id="hogehoge"]のようにすると、擬似クラスと同じ扱いになるので一応解決できるが、そもそもそこまでしてIDを使う必要あるのかな？という問題があるので、使っていない。idかclassで迷う暇があったら命名に時間を使った方がいい。

あとheaderは、固有だからid使って問題ないっしょって思ってる人。スクロールしたら見た目が少しだけ変わるヘッダーを見たことはないですか？
ああいうのを実装するときは僕は、jQueryの.clone()を使って実装したくなるのでidを使っているとその時点で積みますね。(実体験)


## 要素名で指定するものは最小限に

しばしば下のようなコードを見かける。

```scss
.list {
	li {
		a {
		
		}
	}
}
```

aタグはともかく、liにもclassをつけないというのはいまいち
理由は、

- 修正が発生した時にliの中に文字以外の要素が入る可能性もある
- 要素で検索するよりclassのほうがはやい(誤差程度ではあるが)

なので、
**基本的に全てにclassをつける。aタグやth,tdは状況に応じて許容するが基本ダメ。**
というルールにしている。


## reset.css or normalize.css
基本的に、下記のCSSを利用する。あとはプロジェクトに応じて随時はじめからスタイルを設定しておく
https://github.com/BYODKM/nondestructive-reset.css

## 普段書いてる時に◯◯で悩んでいる！というのがあったら教えて下さい！
普段無意識レベルでやっていることが意外にみなさんが悩んでいることかもしれないので、よかったら共有していただけたら上に追加するかもしれません！