CSS
コンポーネント
CSS設計

コンポーネント時代に適した独自CSS設計を考えた[構想編]

CSSの設計で色々と悩んだ末に
既存の設計ではしっくりこなかったので、独自の設計を考えてみました。

独自設計は、Base, Layouts, Objects, Modifiers というレイヤーに分けて、BLOMと名付けました。

BLOMの良さは
・レイアウトとコンポーネントのスタイリングを分離できる
・構造の理解がしやすい
・React、Vue、あるいはAtomicDesignなどと組み合わせることも容易
などが有ると思っています。

なお、内容をまとめるにあたって、以下の2記事に分けようと思います。
構想編: 本記事。CSS設計の構想を考えてみました。
実践編: 現在、実際に導入・運用し始めたところなのですが、そこでの気づきをまとめます。後日公開予定。

コンポーネントの時代

近年、フロントエンドでは、React, Vue, WebComponents, Polymer
などなど、コンポネートベースのライブラリが人気を博しています。

一方でデザイン領域でも、AtomicDesignの台頭や、Sketchのシンボルという機能(デザイン要素を簡単に継承できるもの)などによって、
コンポーネントを作り、その組み合わせによってページを作っていくというフローが、
もはや当たり前のものになってきていると感じます。

コンポーネントをベースに考え、設計することはとても有用だと思います。
一度作れば使い回しができ、修正も内部に閉じているため余計な影響を考える必要が減ります(上手く設計できていれば、ですが)。

さらに、デザイナーが管理するコンポーネントと、エンジニアが実装するコンポーネントの粒度を揃えれば、デザイナーが行った修正を本番に反映させるのも非常に簡単です。

※フロントエンドはエンジニアが修正することを想定していますが、デザイナーがコーディングも担当している組織でも実装が楽になるのは同じだと思います。

既存のCSS設計を調べる

さて、デザイン実装は基本的にCSSです。
(最近はReactのstyled-componentsを試したりもしました。が、まだCSSを完全に置き換えるには一歩足りないと思っています。)

CSSを設計無しに実装すると地獄を見るのはもはや常識ですね?
個人的には、BEMを取り入れて、それだけでもかなりの秩序を得た経験が有りますが、
せっかくコンポーネントの時代ですから、その利便性を享受できるような設計を取り入れましょう。

さて、CSSの設計は少しググってみると、たくさん出てきます。
OOCSS, SMACSS, FLOCSS…
この記事を下書きで温めているうちに、良いまとめ記事が公開されていました。
https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a

既存のCSS設計の中で、コンポーネント中心のデザインと相性が一番良さそうなのは、
FLOCSSでした。

FLOCSSを導入してみたが…

FLOCSSの詳細については他の記事や公式GitHubによくまとまっているので、そちらをご参照いただきたいのですが、
FLOCSSは良さそうだと思ったので、実際に採用してみました。
特に良いと思った点は、コンポーネントとレイアウト(要素の配置)が分離できそうなところでした。

しかし、いざ導入してみると、少し扱いにくい部分も見えてきました。

  • utilsがどんどん太っていく。marginpaddingはよく使う。colorbackground-colorもよく使う。全部がutilsに有ると、分割したくなります。 しかし分割をしようにもディレクトリのネストが深くなってしまうのでイマイチ。
  • ComponentレイヤーとProjectレイヤーの役割分担が難しい。 これは他の記事でもよく指摘されていました。複数回出現したらComponentとするなどの対策も有りましたが、運用が面倒臭そうです…

もちろん良かった点も有ります。

  • レイアウト(配置)とコンポーネントを分離できた。(当初の狙い通り)marginも分離できるので、コンポーネントは自身の内側のみに集中でき、再利用性の高いものが作れる。
  • utilsでの修正が便利。「この要素のfont-sizeだけ変えたいな〜」という時に、わざわざ新しいclassを定義する必要が無い。

そこで、
FLOCSSに大いにインスパイアされつつ、独自に設計を考えてみることにしました。
ReactやVue、あるいはAtomicDesignなど、実装方法や設計思想が多少変わっても通用するようにしたいとも考えました。

BLOM [独自のCSS設計構想]

FLOCSSから、個人的に扱いづらかった点を修正し、独自設計を考えてみました。
冒頭でも紹介しましたが、BLOMと名付けました。

各レイヤーについて

Base

FLOCSSのFoundationと同様。
Baseという命名は、FLOCSSのFoundationでも良かったものの、より馴染みやすそうなBaseとした。(どちらでも良い)

Layouts

要素配置を指定する。(※FLOCSSとは指定の仕方が違います。後述。)
marginやpaddingもココで定義します。

Objects

コンポーネントのデザインはここで行います。

Modifiers

色やサイズの調整を司る。コンポーネントのデザインを上書きするなど。
例えば、「このボタン、デザインそのまま色だけ変えたいなー」といった時に使えます。
あるいは「ここのテキスト、フォントサイズだけ変えたいんだけど、そのために新しいクラス作るの面倒だなー」という時にも使えます。

全体像

さらに各レイヤー内でも役割によってファイルやディレクトリを分けます。
全体のファイル構成例は下記のようになります。
(scssを前提としています。)

- base
  - reset.scss
    (normalizeでもsanitizeでも)
  - constants.scss
    (定数定義)
  - site-settings.scss
    (html,body,a などにデフォルト設定を付ける)
- layouts
  - alignments.scss
    (flexboxなどの配置用classを定義)
  - spaces.scss
    (marginとpadding)
- objects
  この中身は置き換え可能です。以下は一例。
  - modules
    (使い回すパーツ)
    - buttton.scss
  - pages
    (ページに独自のスタイル)
    - user-page.scss
- modifires
  - colors.scss
    (color, background-color, border-color を指定)
  - utils.scss
    (色以外のmodifiresを定義)

設計のポイント

  • レイアウトとコンポーネントの分離。FLOCSSのLayoutは、headersidebarのようなものでしたが、ここでは、より汎用的な、縦並びや横並びなどの配置を指定するクラスのみを定義します。flexboxがオススメです。
  • Objectsにはコンポーネントのみを配置。AtomicDesignやReactのコンポーネントを導入する場合、このレイヤーのみを入れ替えることで対応可能。
  • Utilsは、Modifiersと名前変更。名前から役割が曖昧だったので、要素の色などを上書き修正するもの、と分かるようにしました。
  • margin, paddingもLayoutsの一部としました。

[どうでも良いこと]
Objectsは、本音を言うとComponentsと命名したいのですが、設計の名称をBLOMとし、読みやすさ(=馴染みやすさ)を優先するため、Objectsとしています。決して妥協では有りません(?)

想定している使い方

  • Base,Layouts,Modifires は一通り定義してしまえば、開発中に修正することはあまり無いです。Objectsのみ、どんどん追加していく運用になると思います。
  • デザイン実装の進め方は、下記の想定です。
    • Layoutsで配置を定義し
    • Objects内のコンポーネントを利用、もしくは新規作成。
    • Modifiersで色などを整える。
  • Objectsの粒度は開発メンバーの馴染みやすさを優先すべきだと思います。 例えば、AtomicDesignに馴染みが有るのであれば、atoms,moleculesなどに分けるのが良いと思います。

prefixについて

FLOCSSのprefixは、各レイヤー全てについていました。(Layoutはl-、Projectはp-、Utilはu-など)
これは、どのHTML側から見たときに、CSSのどのレイヤーに記述されているか分かりやすくなるという利点が有ります。
一方で、FLOCSSに馴染みが無いうちは混乱の種になり、コーディングの際も(一々prefixを付けるのが)若干煩わしいような気がします。
なのでBLOMでは、第一階層のみでも良いと思っています。さらにObjectsはprefix無しでも良いと思います。
するとprefixは、Layoutsのl-、Modifiersのm-のみとなります。
l-で配置、m-で修正。それ以外は全部コンポーネントなので、分かりやすいと思います。

まとめ

本記事では、コンポーネント時代に適した独自のCSS設計を紹介してきました。
以下、本文から要点だけ再掲してまとめとしたいと思います。

  • 独自設計は、Base, Layouts, Objects, Modifiers というレイヤーに分けて、BLOMと名付けました。

  • BLOMの良さは

    • レイアウトとコンポーネントのスタイリングを分離できる
    • 構造の理解がしやすい
    • React、Vue、あるいはAtomicDesignなどと組み合わせることも容易
  • デザイン実装の進め方は、下記の想定です。

    • Layoutsで配置を定義し
    • Objects内のコンポーネントを利用、もしくは新規作成。
    • Modifiersで色などを整える。
  • 全体像は以下の通りです。

- base
  - reset.scss
    (normalizeでもsanitizeでも)
  - constants.scss
    (定数定義)
  - site-settings.scss
    (html,body,a などにデフォルト設定を付ける)
- layouts
  - alignments.scss
    (flexboxなどの配置用classを定義)
  - spaces.scss
    (marginとpadding)
- objects
  この中身は置き換え可能です。以下は一例。
  - modules
    (使い回すパーツ)
    - buttton.scss
  - pages
    (ページに独自のスタイル)
    - user-page.scss
- modifires
  - colors.scss
    (color, background-color, border-color を指定)
  - utils.scss
    (色以外のmodifiresを定義)

そして実践へ…

さて、BLOMという独自設計ですが、実際に運用してみるとどうなるのか、
ちゃんと扱いやすく、破綻しにくい設計となっているのか、などなど、
絶賛検証中です。
実践編では、各レイヤーにおける試行錯誤や、細かい工夫などをまとめられたら良いなと思っております。