シンプルなCSS設計ができるRSCSSに入門してみた

この記事は [WESEEK Advent Calendar](https://qiita.com/advent-calendar/2020/weseek) 2020 5日目の記事です。

# RSCSSに入門してみた

[公式サイト](https://rscss.io/)

## RSCSS とは

CSS設計のためのアイデア集です。  
現在 [GitHub](https://github.com/rstacruz/rscss) の star は 3.8k を超えていてかなり支持されているように見えます。

> It's simply a set of ideas to guide your process of building maintainable CSS for any modern website or application.

と公式にある通り、導入することで構造がバシッと決まるというわけではありません。
がこういったアイデアを知り部分的にでも取り入れることで、コーディング規約のアップデートにつながると思います。

## 提唱されているアイデア
特徴的なアイデアをまとめます。

- コンポーネントの命名
    - 各単語の間にダッシュを入れて、2つの単語で名前が付けられる。
    - `.bookmark-button` や `.drowio-modal` や `tag-labels` のような感じ。
- エレメントの命名
    - 1つの単語で名前をつける。
        - 2単語になってしまう時には、連結して表示する。
        - `firstname` や `submitbutton` のような感じ。
    - 子セレクター(`>`)を使用する。
- バリアントの命名
    - `-`から始める。
    - `-disabled` や `-info` のような感じ。
- CSS構造
    - 1コンポーネントを1ファイルごとにまとめる。
    - 個々のUIパーツごとに完結させることができる。

他にもレイアウトやヘルパーという考えがありますが、一旦割愛します。

## 実践してみる

- 弊社プロダクト [GROWI](https://growi.org/ja/) の LikeButton を RSCSS に沿って書いてみます。
    - https://github.com/weseek/growi/blob/master/src/client/js/components/LikeButton.jsx#L43-L54

### RSCSS適応前

```js:original
<button
  type="button"
  id="like-button"
  onClick={this.handleClick}
  className={`btn btn-like border-0 ${pageContainer.state.isLiked ? 'active' : ''} ${isGuestUser ? 'disabled' : ''}`}
>
  <i className="icon-like mr-3"></i>
  <span className="total-likes">
    {pageContainer.state.sumOfLikers}
  </span>
</button>
```

```scss:original
.btn-like {
  height: 40px;
  font-size: 20px;
  border-radius: $border-radius-xl;
}

.total-likes {
  font-size: 17px;
  font-weight: $font-weight-bold;
}
```
※ bootstrap の ユーティリティを使っているので一部抜粋

### RSCSS適応後

```js:apply-rscss
<button
  type="button"
  id="like-button"
  onClick={this.handleClick}
  className={`like-button
  ${pageContainer.state.isLiked ? '-active' : ''} ${isGuestUser ? '-disabled' : ''}`}
>
  <i className="icon"></i>
  <span className="count">
    {pageContainer.state.sumOfLikers}
  </span>
</button>
```

```scss:scss
.like-button {
  height: 40px;
  font-size: 20px;
  border: 0;
  border-radius: .35rem;

  & .-disabled {
    cursor: not-allowed;
    opacity: .65;
  }
    
  & .-active {
    color: #09daff;
  }
    
  & > .icon {
    margin-right: 1rem;
  }
    
  & > .count {
    font-size: 17px;
    font-weight: $font-weight-bold;
  }
}
```
- class 名を短く簡易に記述できる。
    - Components との親子関係によって同一性を担保している。
    - そのため、icon や count など子供のコンポーネントは命名を深く考える必要がない。 
- scss を確認することで html の構造を予測できる。
    - バリアントを使ってここのスタイルを記述できるため動的なスタイルが想像できる。
- ネストは1回までとルールで決まっているので破綻しづらい。
    - 前述の1ファイル1コンポーネントのルールもあってコンポーネント思考との相性は良さそう。

## ユーティリティファーストとはアプローチが逆 :scream: 
実際に入門してみて思ったことを書いていこうかなと。  

> Sometimes, when nesting components, your markup can get dirty

と、公式ページにあり、アプローチとしてなるべく マークアップはシンプルになるような思想があります。

style はコンポーネントに依存した形で構成されその結果、
セットで使うことを前提としているため、マークアップ側の柔軟性が損なわれるように思いました。

普段私は[ユーティリティ・ファースト](https://tailwindcss.com/docs/utility-first)に触れています。
ユーティリティ・ファースト に則ると　class attribute が長くなりますが、マークアップをみるだけで style を想像できます。

個人的には、class をなるべくシンプルにという RSCSS の考えはとてもいいなと思いましたが、拡張性的に合わないかなと感じました。

フレームワークを用いない小規模なライブラリの開発などで試してみようと思います。

※この記事は [WESEEK Tips wiki](https://tips.weseek.co.jp/) に 2020/12/4 に投稿された記事の転載です。
Tips wiki では、IT企業の技術的な情報やプロジェクトの情報を公開可能な範囲で公開してます。