[BEM to RSCSS] Quick Migration Guide

# RSCSSとは

> Styling CSS without losing your sanity

正気を保ってCSSを書くためのアイデア。
ルールではないため、シンプルにするためなら無視しても問題ない。

# BEMとRSCSSの比較

* 命名規則
  - BEMはBlock、Element、Modifierを一つのクラスに連結する
  - RSCSSはそれぞれ単独のクラスとして定義する
* 親子関係
  - BEMはBlockとElement、ElementとElementの親子関係は厳密ではない
  - RSCSSはすべてのセレクタを親子関係として定義する
* ネスト
  - BEMはネストの制約はない
  - RSCSSのネストの深さは必ず１で、コンポーネントからの親子関係で指定する

# 構成する要素

## BEM

* Block: 単独で意味のあるまとまり
* Element: 単独では意味を持たない、ブロックに結び付けられた要素
  - クラスを`__`で接続する
* Modifier: ブロックまたはエレメントのフラグ
  - クラスを`--`で接続する

```sass
.product-list
  &__item
    &--pickup
    &__name
    &__description
```

```html
<ul class="product-list">
  <li class="product-list__item">
    <h3 class="product-list__item__name">Product #01</h3>
    <p class="product-list__item__description">Lorem ipsum dolor sit amet.</p>
  </li>
  <li class="product-list__item product-list__item--pickup">
    <h3 class="product-list__item__name">Product #02 - Pickup!</h3>
    <p class="product-list__item__description">Lorem ipsum dolor sit amet.</p>
  </li>
</ul>
```

## RSCSS

* Component: BEMでのBlock
  - クラス名に必ず`-`を含む**複数単語**で構成する
* Element: BEMでのElement
  - クラス名に`-`を**含まない**
  - 複数単語の場合でも`-`や`_`で連結しない
  - **Componentからの親子関係で指定する**
  - ネストは必ず１つ
* Variant: BEMでのModifier
  - クラス名が必ず`-`で始まる

```sass
.product-list
  & > .item
  & > .item.-pickup
  & > .item > .name
  & > .item > .description
```

```html
<ul class="product-list">
  <li class="item">
    <h3 class="name">Product #01</h3>
    <p class="description">Lorem ipsum dolor sit amet.</p>
  </li>
  <li class="item -pickup">
    <h3 class="name">Product #02 - Pickup!</h3>
    <p class="description">Lorem ipsum dolor sit amet.</p>
  </li>
</ul>
```

# BEMにはないRSCSSの規則

## レイアウト

レイアウトに関するプロパティ（`position`、`margin`、`width`など）はコンポーネントに含めず、更に親のコンポーネントクラスを定義してそこで指定するようにします。

```sass
.article-list
  &
    +clearfix

  & > .article-card
    width: 33.3%
    float: left
```

> [Layout](https://rscss.io/layouts.html)

## ヘルパークラス

`!important`を付与し、最優先でスタイルを外付けしたいときに使用するヘルパークラスを定義できます。
ヘルパークラスは必ず`_`で始めます。

```sass
._unmargin
  margin: 0 !important

._hidden-sp
  @media ($sp)
    display: none !important
```

> [Helpers](https://rscss.io/helpers.html)

## コンポーネントのネスト

コンポーネントをネストする必要があるときは以下の２つのガイドラインを参考に簡単かつ疎結合に定義するようにしてください。

### Variantを使う

コンポーネントをネストさせた際に、子のクラスをコンポーネントで指定するとそのコンポーネント名と密結合なクラスとなっていまします。

```sass
.article-header
  & > .vote-box > .up
    // よくない
```

代わりに、Variantで指定するようにしてください。そうすればコンポーネント名の変更や利用場面の自由度があがります。

```html
<div class="article-header">
  <div class="vote-box -highlight">
    <div class="up"> ... </div>
  </div>
</div>
```

```sass
.article-header
  & > .-highlight > .up
    // ...
```

### プリプロセッサの`@extend`を活用する

コンポーネントをネストさせることでクラス名が複雑になることがあります。

```html
<div class="search-form">
  <input class="input" type="text" />
  <button class="search-button -red -large">Search</button>
</div>
```

代わりに、Elementと定義した上で`@extend`を使用すれば簡潔に表現できます。

```html
<div class="search-form">
  <input class="input" type="text" />
  <button class="submit">Search</button>
</div>
```

```sass
.search-form
  & > .submit
    @extend .search-button
    @extend .search-button.-red
    @extend .search-button.-large
```

# クラス名のチェック

Stylelintで`stylelint-rscss`というルールセットが利用できます。
このルールセットでは「コンポーネントに`-`が含まれていない」とか「親子として指定してよい上限」などといったルールに違反した記述をチェックすることができます。

> [`stylelint-rscss`](https://github.com/rstacruz/stylelint-rscss)

# リンク

* [RSCSS (Official Document)](https://rscss.io)
* [日本語ドキュメント](https://qiita.com/kk6/items/760efba180ec526903db)