現在のプロジェクトで使用している CSS 設計ルール (BEM ベース) のまとめ

この記事は、現在僕が携わっているひだまりプロジェクト (仮称) で使用している CSS 設計ルールについてまとめたものです。

# ベースとなる CSS 設計

* [BEM (MindBEMding)](http://csswizardry.com/2013/01/mindbemding-getting-your-head-round-bem-syntax/)
   * BEM 自体についての説明は省略します。
   * 一部 [SMACSS](https://smacss.com/ja) を参考にした独自ルールを取り入れています。詳しくは後述します。

# ルール

## (1) Element をネストしない

BEM を使用する際の大原則として `block__element` という対応関係を厳守します。

### NG

`category__item__name` は `block__element1__element2` と Element がネストしています。

```html
<head>
  <style>
    .category-list {}
    .category-list__item {}
    .category-list__item__name {}
  </style>
</head>
<body>
  <div class="category-list">
    <div class="category__item">
      <span class="category__item__name"></span>
    </div>
  </div>
</body>
```

### OK

`category-list__item` の `item` は `category-list` という Block の Element である一方で、
`name` という Element を持った `category-item` という Block でもあるとみなします。

```html
<head>
  <style>
    .category-list {}
    .category-list__item {}
    .category-item {}
    .category-item__name {}
  </style>
</head>
<body>
  <div class="category-list">
    <div class="category__item category-item">
      <span class="category-item__name"></span>
    </div>
  </div>
</body>
```

## (2) Modifier の代わりに SMACSS の State を使う

ひだまりプロジェクトの独自ルールとして、BEM の Modifier の代わりに SMACSS の State ルールを使うようにしています。
State ルールでは `is-` あるいは `has-`というプレフィックス付きのクラスを使用します。本ルールではこれを Modifier 付きのクラスの代わりに使用します。 
このルールを用いることで、Modifier を用いる際にセレクタ記述が冗長になってしまうのを防ぐことができます。
これは JavaScript (jQuery) でクラスを追加したり削除する場合にも都合がいいです。

### NG

HTML

```html
<head>
  <style>
    .category-item {}
    .category-item--focused {}
  </style>
</head>
<body>
  <div class="category-item category-item--focused">
    <span class="category-item__name"></span>
  </div>
</body>
```

JavaScript

```js
var block = 'category-item';

$('.' + block).addClass(block + '--focused');
```

### OK

HTML

```html
<head>
  <style>
    .category-item {}
    .category-item.is-focused {}
  </style>
</head>
<body>
  <div class="category-item is-focused">
    <span class="category-item__name"></span>
  </div>
</body>
```

JavaScript

```js
$('.category-item').addClass('is-focused');
```

## (3) 原則としてセレクタをネストしない

原則としてセレクタをネストしてはいけません。それぞれのセレクタを独立させます。
Sass を使用する場合も、CSS にコンパイルした後でセレクタがネストしないようします。
具体的には `&` ([Referencing Parent Selectors](http://sass-lang.com/documentation/file.SASS_REFERENCE.html#parent-selector)) を使用します。

### NG

Sass

```scss
.category-list {
  .category-list__item {}
}
```

CSS

```css
.category-list .category-list__item {}
```

### OK

Sass

```scss
.category-list {
  &__item {}
}
```

CSS

```css
.category-list {}
.category-list__item {}
```

## (4) Block に State を適用する場合は Element のセレクタをネストする

Block に State ルールを適用し、それが Element にも影響する場合は、ルール (3) の例外としてセレクタをネストさせます。
これは State の指定が冗長になるのを防ぐためです。
ただし、影響範囲が最小となるように、可能であれば子セレクタ `>` を使用します。

### NG

Sass

```scss
.category-item {
  &.is-focused {}
  &__number {
    &.is-focused {}
  }
  &__name {
    &.is-focused {}
  }
  &__description {
    &.is-focused {}
  }
}
```

CSS

```css
.category-item.is-focused {}
.category-item__number.is-focused {}
.category-item__name.is-focused {}
.category-item__description.is-focused {}
```

### OK

Sass

```scss
.category-item {
  $block: &;

  &.is-focused {
    // & > &__name
    // のように Block の部分に & を使うと、コンパイル後に
    // .category-item.is-focused > .category-item.is-focused__number
    // と変換されてしまう。
    & > #{$block}__number {}
    & > #{$block}__name {}
    & > #{$block}__description {}
  }
}
```

CSS

```css
.category-item.is-focused {}
.category-item.is-focused > .category-item__number {}
.category-item.is-focused > .category-item__name {}
.category-item.is-focused > .category-item__description {}
```

# 参考

* [BEMる](http://memo.brdr.jp/post/72864028202/bem%E3%82%8B)
* [BEM 化されたブログをのぞかせてもらう](http://chroma.hatenablog.com/entry/2013/12/13/113334)
* [Using BEM in the Real World: Pitfalls & Advice](http://sugarenia.com/blog/bem-pitfalls-advice/)
   * SMACSS の State を使うアイディアは、この記事を参考にしました。