FLOCSSを使ったCSS設計での悩みどころと解決案

# はじめに
`FLOCSS`というCSS設計手法で実装をやっていく上で、唯一の悩みどころに`component`と`project`の判別があります。私のチームでも悩み、チームメンバーがモヤモヤし、あとあとCSSも崩壊しそうだったので、一つの判別基準をつくることにしました。

<img width="254" alt="スクリーンショット 2018-04-16 9.18.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/50783/4721df7a-b461-825b-50b9-7bcde91f2497.png">


## `FLOCSS` とは
数あるCSS設計手法のひとつで、OOCSSやSMACSS、BEM、SuitCSSなどのメジャーな設計手法のいいとこどりをした国産の設計手法です。
https://github.com/hiloki/flocss

CSSはデザイン通りの見た目を実現するために様々な書き方ができてしまうため、あるルールに則って記述していかないと、一つの変更が予期せぬところのレイアウト崩れを発生させてしまいます。そのルールというのも、かなり練りこんだものでないとあとあと破綻してしまいます。

FLOCSSはそういった要点を抑えたうえで、UIパーツを以下のようなレイヤーに分類するという特徴をもちます。

1. **Foundation** - reset/normalize/base...など
2. **Layout** - header/main/sidebar/footer...など
3. **Object**
 - **Component** - grid/button/form/media...など
 - **Project** - articles/ranking/promo...など
 - **Utility** - clearfix/display/margin...など

# FLOCSS設計の悩みどころ
開発していると、ここの中の２つのレイヤー`component`と`project`の判別に悩みます。

>**ComponentとProjectの定義**
**1． Component**
再利用できるパターンとして、小さな単位のモジュール。 例えばBootstrapのComponentカテゴリなどに見られるbuttonなどが該当。 出来る限り、最低限の機能を持ったものとして定義されるべき。
**2． Project**
プロジェクト固有のパターンであり、いくつかのComponentと、それに該当しない要素によって構成されるものを定義する。 例えば、記事一覧や、ユーザープロフィール、画像ギャラリーなどコンテンツを構成する要素などが該当する。
https://github.com/hiloki/flocss より抜粋



人間で言えば、裸んぼの人間が最小単位のモジュール`component`で、他にネクタイや靴下、スーツといった`component`があり、組み合わせてビジネスマン`project`になると考えられますが、

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f35303738332f62366162623038392d386463322d336134372d313138612d6266623538333239326430332e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/50783/48cb2d98-f343-dfc7-9f52-8c1c5cce5b56.png)


人によってはhumanはさらに細かくできるのでは？と思うかもしれません。
この考え方の違いによってhumanが`component`なのか`project`なのかが違ってきます。

<img width="546" alt="スクリーンショット 2018-04-13 1.32.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/50783/1cc04144-feb2-a204-77bd-251df6647dc7.png">

具体的なUIパーツを例にあげると以下のような`card`の場合です。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f35303738332f33356439313366332d623635632d316566382d613566632d3430656466623763386631352e706e67.png](https://qiita-image-store.s3.amazonaws.com/0/50783/9a2be5b4-f034-69fa-c70e-f4a10b8310f8.png)



この最小単位の判別が実装者によってバラバラだと、あとあとcss設計が破綻してしまいます。



この問題に対して、他の方々は独自ルールで仕分けしているようです。

>*プロダクトの中で4回以上同じ Object が登場したらそれは Component に分類*
>[FLOCSSを使ってCSSファイルを20,000行から9,000行にした話](https://qiita.com/Atsss/items/4f9d98fb1d0546539c09)

>*Atomic Designでいう、AtomsをComponent、Molecules等Atoms以外をProjectとしました。
再利用性の高い粒度の小さいコンポーネントがComponentのイメージです。*
>[脱・CSS無法地帯。FLOCSSで指針のある設計を。](https://qiita.com/sueshin/items/dcbaf3d8a0adb6b087db)

とても参考になりましたが、私がいる開発現場では以下のような問題がありました。

- ABテストを繰り返して開発を続けているため、UIパーツの出てくる回数を最初には決められない
- `Atomic Design`の考え方だと、今度は何が`Atoms`になるのか？と悩むことに

我々にはチーム全員が機械的に共通した仕分けができる方法が必要でした。

# 考えついた仕分け方
チーム全員が「**これは最小単位のモジュールだ**」と機械的に判別できるものを探しました。

そこで辿りついたのが**PowerPointの図形**です。

![download.png](https://qiita-image-store.s3.amazonaws.com/0/50783/eede5f9f-a9b7-29c9-2449-5180bf9b37f6.png)

![スクリーンショット 2018-04-13 18.04.53.png](https://qiita-image-store.s3.amazonaws.com/0/50783/c6ec3888-701d-cb60-c880-16688057db64.png)

この**PowerPoint**の図形を使って以下のように`component`と`project`を定義しました。

- `component`：パワポの図形１つの単位
- `project`：グループ化して動かす単位

この考えでいくと、例えば次のように仕分けすることができます。

![スクリーンショット 2018-04-13 18.48.55.png](https://qiita-image-store.s3.amazonaws.com/0/50783/0f9e1f7e-bb12-efb4-42ac-67eaf7b1edb0.png)

上の例では`project`にも**button**があります、これをつくることでボタンの中にアイコンをいれたボタンをつくりたい場合に、最小単位のアイコンを、最小単位であるはずのボタンが制御しなければはならないというジレンマを解消します。

これにより`c-button`を最小構成に保つということを守りつつ
アイコンや他のUIパーツを組み合わせたボタンを作成することができます。

以下は実装例です。
`c-`のついたUIパーツは`component`を表しており、それ自体に位置などは指定せず、色などの見た目だけを指定しています。　そして、`p-`のついた`project`はそれら`component`の位置を指定します。
<p data-height="265" data-theme-id="0" data-slug-hash="qozLGL" data-default-tab="css,result" data-user="uga" data-embed-version="2" data-pen-title="FLOCSS Sample - button" class="codepen">See the Pen <a href="https://codepen.io/uga/pen/qozLGL/">FLOCSS Sample - button</a> by UGA (<a href="https://codepen.io/uga">@uga</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

`c-thumbnail`は画像である場合が多いので、見た目を変更することがなく、場合によっては不要かもしれません。つまり、かならず`project`の中に`component`があるというわけではありません。

`c-thumbnail`が必要になる場合は、たとえば必ず`border-radius: 4px`を指定する場合が考えられますが、これはデザイナーと相談して決めることになります。

# まとめ
`FLOCSS`の`component`と`project`の判別を迷わないために、**PowerPointの図形**を使って以下のように決めました。

- `component`：パワポの図形１つの単位
- `project`：グループ化して動かす単位

とりあえずこれでチーム全員が「**これは最小単位のモジュールだ**」と判別できる基準をもつことができました。

## 余談ですが
当初、IllustratorやPhotoshopでの判別を考えていましたが、図形とテキストが別なのでうまくいきませんでした。
PowerPoint以外では、もちろんKeynote、ExcelやWord、Draw.ioでも大丈夫です。