BEMの命名規則とスタイルの当て方について


BEMの命名規則がいまいち分からない方は必見。
またスタイルを当てていると、いざ変更があった場合に依存関係に困ることがある人も多いハズ。
個人的な書き方を備忘録として書いておく。

# おさらい

## Block
構成のルートとなる要素。この要素はどこにでも置くことのできる、独立して動作するもの。

## Element
Blockに紐付いて定義される子要素。Blockの要素内のパーツであり、Block要素なしでは動作しないもの。

## Modifier
元となるBlockまたはElementの要素から変化した状態を表す要素。元となる要素なしでは動作しないもの。

# 命名規則

Block, Element, Modifierは全て`kebab-case`で記述する。
Block-Element間は`__`で接続する。
Block-Modifier間、Element-Modifier間は`_`で接続する。
Modifierは状態の名前と値をセットにし、`-`で接続する。

# 例

## Block
`.box`

```html
<div class="box">
</div>
```

```css
.box {
}
```

## Block + Element
`.box`, `.box__title`, `.box__description`

```html
<div class="box">
  <div class="box__title">タイトル</div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
}

.box__title {
}

.box__description {
}
```

## Block + Modifier
`.box`, `.box_col-wh`

```html
<div class="box box_col-wh">
  <div class="box__title">タイトル</div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
  background-color: #000;
}

.box__title {
  background-color: #fff;
}

.box__description {
}

.box_col-wh {
  background-color: #fff;
}

.box_col-wh > .box__title {
  background-color: #000;
}
```

Blockの要素の状態の変化を表現したパターン。
この場合、boxの背景が白になったり、それに依存してtitleが変化して、 **box全体の状態を変化させる** イメージ。

## Element + Modifier
`.box__title`, `.box__title_col-wh`

```html
<div class="box">
  <div class="box__title box__title_col-wh">タイトル</div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
}

.box__title {
  background-color: #000;
}

.box__title_col-wh {
  background-color: #fff;
}

.box__description {
}
```

Elementの要素の状態の変化を表現したパターン。
Block + Modifierとの違いとして、 **boxの状態は変化させず、それに依存しない形でtitleを変化させたい** 場合、こちらを選択すべきである。

## Block + Element + Element
`.box__title__icon`

```html
<div class="box">
  <div class="box__title">
    <i class="box__title__icon"></i>
    タイトル
  </div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
}

.box__title {
  position: relative;
}

.box__title__icon {
  content: '!';
  position: absolute;
  left: 0;
}

.box__description {
}
```

ただし構造を見て、依存関係を見直してもよい場合がある。
この場合、表示位置はtitleとiconの間に依存関係はあるが、見た目に依存関係はないので、下のように分けるべきである。

```html
<div class="box">
  <div class="box__title">
    <i class="icon box__title__icon"></i>
    タイトル
  </div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
}

.box__title {
  position: relative;
}

.box__title__icon {
  position: absolute;
  left: 0;
}

.box__description {
}

.icon {
  content: '!';
}
```

## Block + 複数のModifier
`.box`, `.box_col-wh`, `.box_size-s`

```html
<div class="box box_col-wh box_size-s">
  <div class="box__title">タイトル</div>
  <div class="box__description">説明</div>
</div>
```

```css
.box {
  background-color: #000;
}

.box__title {
  background-color: #fff;
}

.box__description {
}

.box_col-wh {
  background-color: #fff;
}

.box_col-wh > .box__title {
  background-color: #000;
}

.box_size-s {
  width: 100px;
}

.box_size-s > .box__title {
  font-size: 0.5rem;
}
```

Blockの要素の状態の変化が複数だった場合を表現したパターン。
この場合、`.box_col-wh`で色周りが変化し、`.box_size_l`でサイズ周りが変化しているが、
お互いに依存しないようにすることで、それぞれの状態を選択できるようになる。

```html
<div class="box box_col-wh box_size-s">
</div>

<div class="box box_col-wh">
</div>

<div class="box box_size-s">
</div>
```