自分なりのCSS設計について考えてみる

# 経緯

最近、CSS設計をする機会が多かったのですが、要望を満たせるものがなく、それなら自分なりに考えてみようと思いました。
僕自身は、サーバーサイドの開発から始まり、CSSの設計を行うようになったため、デザイナーではありません。
そのため、デザインのスキルはなく、デザインを見て、CSS設計を行うという形になっています。
また、開発を行う中で、HTML+CSSの工数が大きいため、ここの部分を効率化するために、いろいろ考えました。

Atomicデザインや、FLOCSSなどの導入を検討中ですが、新しい方法を考えてみるのも面白いかなと思い、試してみました。

**※思いつきレベルなので考慮できていないことも多いと思います。
「そんな考えもあるんだ」くらいの感覚でお願いします。**

# 置かれている環境

このようなことになった経緯を簡単に説明したいと思います。

#### 既存のCSS設計に当てはめられない

結局、デザイナーの方がCSS設計を知らないとそうなります。
**なんとなく使い回しができそうな感じでデザインしてくれても、CSSにするといい感じに共通化できなかったり…。**

#### コンポーネント化してもサイズ違いがどんどん出てくる

最初に想定していたサイズを無視されたデザインがでてくることが多かったです。
BEMのmodifierで対応できる範囲であればいいのですが、そんなことはなかったです。

# 設計手法

大まかなディレクトリは下記のようになると思っています。

* component
* block
* page
* utility

## component

よくあるコンポーネントです。
ボタンとか、カードとか、大小問わず入れていきます。
注意としては下記のルールで入れていきます。

* 全体の横幅は指定せず親要素で制御される
* BEMでいうBlock（一番の親要素）には、外に影響するプロパティを持たない
    * 　margin とか

また、AtomicデザインやFLOCSSのように分けた方がいいかもしれないですが、現状ではそこまではいいかなと思っています。
もしかしたら、今後分けるかもですが・・・。

## block

汎用的な配置を管理するためのクラスを入れます。
現状で考えているのは、等間隔の横並べです。
グリッドシステムをより簡略化して、余白を管理しやすくするのが目的です。
それ以外は、コンポーネントが管理すればいいという考えです。
画像とテキストの横並べで、画像のpx固定とか。
重要なのは、**先ほどのコンポーネントをこの中に入れて使用する**ということです。

下記のようにflexbox系のプロパティを指定します。
必要に応じて、modifierを増やしてください。

``` scss
.b-block {

  width: 100%;
  display: block;

  &--2 {
      display: flex;

      >* {
          width: 50%;
      }
  }

  &--3 {
      display: flex;

      >* {
          width: percentage(1/3);
      }
  }
}
```

## page

blockやheaderやfooterなどを配置を管理します。

## utility

よくあるユーティリティ系をまとめるところです。
marginとかpaddingなど、ちょっと修正したいときに使用するものを入れます。
特殊なのは、上記の横並べの余白を制御するCSSになります。
下記のようなものを用意しました。

```scss
.u-gap {
  @for $i from 1 through 10 {
    &#{$i * 5}px {
      & > * + * {
        margin-left: #{$i * 5}px;
      }
    }
  }
}
```

# 使用例

使用するために、仮のコンポーネントとして下記を使用します。

```scss
.c-block {
  border: solid 1px #333;
  padding: 10px;
  
  &__title {}
  &__container {
    margin-top: 15px;
  }
}

.c-title {
  font-size: 24px;
  line-height: 1.35;
  font-weight: bold;
}

.c-box {
  background-color: #ccc;
  text-align: center;
  font-size: 16px;
  padding: 10px;
}
```

これらのクラスを付与したHTMLです。

```html
<div class="c-block">
    <div class="c-block__title">
        <p class="c-title">boxを２つ内包</p>
    </div>
    <div class="c-block__container">
        <div class="b-block b-block--2 u-gap10px">
        <div class="c-box">box</div>
        <div class="c-box">box</div>
        </div>
    </div>
</div>
```

こんな感じになります。
`b-block b-block--2 u-gap10px`と指定しているので、２カラムで間を10px開けるという指定になります。

<img width="794" alt="スクリーンショット 2018-10-21 3.03.50.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/295cade3-d0d3-7329-352e-45cef7ec5473.png">

次は、上記のc-blockをさらに入れ子にしてみます。

```html
<div class="c-block">
    <div class="c-block__title">
        <p class="c-title">boxを２つ内包したものを2つ内包</p>
    </div>
    <div class="c-block__container">
        <div class="b-block b-block--2 u-gap10px">
        <div class="c-block">
            <div class="c-block__title">
            <p class="c-title">boxを２つ内包</p>
            </div>
            <div class="c-block__container">
            <div class="b-block b-block--2 u-gap10px">
                <div class="c-box">box</div>
                <div class="c-box">box</div>
            </div>
            </div>
        </div>
        <div class="c-block">
            <div class="c-block__title">
            <p class="c-title">boxを２つ内包</p>
            </div>
            <div class="c-block__container">
            <div class="b-block b-block--2 u-gap10px">
                <div class="c-box">box</div>
                <div class="c-box">box</div>
            </div>
            </div>
        </div>
        </div>
    </div>
</div>
```

CSSは全く修正しなくても下記のようになります。
いい感じに入れ子にできました。

<img width="790" alt="スクリーンショット 2018-10-21 3.06.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/155990/b7422fab-6fd4-05d5-29a6-a639fa80b50f.png">

# まとめ

まだまだ思いつきレベルですが、こんな感じのものを考えてみました。
グリッドシステム＋FLOCSSみたいなものじゃん、という感じかもしれないですが…。

進展あれば報告していきたいと思います。