新年なのでCSSの設計思想について語ってみた

2021.01.12

2021.08.12

Fabeee社員ブログ

やあやあ皆さん、こんにちは。
Fabeeeのアイドル、みーちゃんです。(大嘘)

新年明けましておめでとうございます。
お仕事も始まったということで、皆さん調子はよきでしょうか?
私はというと、年末年始は朝から晩までゲーム三昧の日々を過ごして折りました。
社会人復帰絶不調です。
ということで、早速本題に入りましょう。
これでもフロントエンドエンジニアとしてやってきました。(できるとは言ってない。)
自身のおさらいがてらにCSSの設計思想について語らせて頂きます。
なにも考えずにCSSを書いてるとごちゃごちゃしがちですからね。
いい感じにCSSを組めたらみんなハッピーなのではないでしょうか。
ということで、今回紹介するのはこちら。
FLOCSS!!!
下記がざっくりとしたアジェンダとなっております。

 

FLOCSSとは

FLOCSSとは、
Foundation Layout Object CSSの略で、「フロックス」と読みます。
OOCSSやBEM、SMACSSのいいとこ取りをしたCSS設計思想って感じです。
再利用性や拡張性を意識しながら`モジュール単位でマークアップやCSSを書く`というのがFLOCSSの基本ルールとなります。
オブジェクト指向で設計されています。
CSSのファイルを用途ごとに分けて、再利用しやすくし、見通しも良くしていこうといった感じです。
「OOCSSとかBEMとかSMACSSとかよくわからない〜」と嘆いてるぴえんなあなた。
FLOCSSを意識することでいい感じのCSS設計になって、CSSの見通しもよくなると思ってもらえればよきです。
では、FLOCSSのファイル構造について説明します。
大きく分けて、FoundationLayoutObjectの3つの構造(レイヤー)で成り立っております。
Objectレイヤーのみ、サブレイヤーというさらに細かいレイヤーで成り立っております。
ではでは、各レイヤー陣を紹介致しましょう。
 

レイヤー

Foundation

サイト全体のデフォルトスタイルを管理。
ブラウザのデフォルトスタイルの初期化やプロジェクトの基本スタイルなどを定義します。
sassの場合は変数やMixin、Functionなども定義します。
reset.scssbase.scssvariable.scssmixin.scssが属します。

Layout

各ページを構成するサイト全体で共通したエリアを管理。
headerやメインのコンテンツエリア、サイドバーやfooterなどのプロジェクト共通ブロックのスタイルを定義します。
l-header.scssl-main.scssl-footer.scss等が属します。
「ファイル名についてるl-ってなぁに?」という疑問をお持ちのあなた。
このlはLayoutレイヤーの頭文字のlです。
「Layoutに属してるファイルだよ」って感じです。
Foundation以外のファイル名には、属するレイヤー,サブレイヤーの頭文字をつけてあげましょう。

Object

サイト全体で再利用できるパターンを持つモジュールを管理。
こいつは更に分解されて、ComponentProjectUtilityの3つで構成(サブレイヤー)されます。

Component

パターンとして再利用できる汎用的なモジュールを定義
フォームやボタンなど汎用的な要素を定義します。
c-form.scssc-button.scss等のファイル名になります。

Project

プロジェクト固有のパターンを管理
記事一覧、画像ギャラリーなどコンテンツを構成する要素を定義します。
Componentを組み合わせたものがProjectだと思ってもらえればよきなんじゃないですかね。
Componentにするには大きすぎる、、!って悩んだらここに書いときましょっ。
p-article.scssp-images.scss等のファイル名になります。

Utility

スタイル調整に使用するヘルパークラスを管理
ComponentやProjectの補助的役割をするコードを定義します。
.u-mt10 { margin-top: 10px }てきなクラスの集まりですね。
全ての余白をUtilityクラスで定義するのはNGです。
u-margin.scssu-color.scss等のファイル名になります。
「Utilityクラスそんなになくね?」という場合は、u-utility.scssに全部まとめてもよきだと思いますね。
以上がFLOCSSレイヤー軍の説明になります。
文字じゃわかりづらいという方のためにとても簡易的な図も用意しました。

こんな感じでファイルを細分化し、再利用しやすいCSSを設計していこうって感じです。
 

命名規則

では続きまして、FLOCSSのクラス命名規則についてお話していきます。

プレフィックス

モジュールがどのレイヤー/サブレイヤーに属しているかわかりやすくするために、class名にレイヤー/サブレイヤーの頭文字をつけます。
Layout: .l-*
Component: .c-*
Project: .p-*
Utility: .u-*

BEM

BEMとはBlockElementModifierの頭文字となっております。
つまり、「この3つの構成に従ってクラス名をつけていきましょうね」っていう命名規則です。
この3構成はなんぞやといいますと、

  1. Blockはそのクラスの一番大きな括りになります。
  2. ElementはBlockの中にいる要素です。
  3. Modifierは装飾などの調整になります。

このルールに従うと下記のようなクラス名が完成します。

.Block__Element--Modifier

Elementの前には”__”アンダースコアを2つ、
Modifireの前には”–“ハイフンを2つつけます。
ちなみに、絶対3つの要素で構成しなければいけないわけではないです。
下記のようになるケースもあります。

.Block
.Block__Element
.Block--Modifier

ボタンのコンポーネントを例にあげると下のような感じになります。

.button {}
.button--red {}
.button__text {}
.button__text--red {}

ちなみに、プレフィックスをつけてあげるとこんな感じです↓

.l-Block__Element--Modifier
.c-button__text--redしたのか

CSSのレンダリングについて

ここでCSSの余談をさせてください。
まず、CSSにはCSSセレクタとCSSプロパティがあります。

body div .button { /* ← CSSセレクタ(タグ名やクラス名) */
/* ↓ここに記載するのがCSSプロパティ */
color: red;
}

実は下記のようなCSSの書き方は、レンダリングの処理速度的にあまり良くないのです。
1. CSSセレクタを細かく書く
2. HTMLタグにCSSプロパティをあてる

1. CSSセレクタを細かく書く

CSSのスタイルとHTMLをマッチングさせる際、CSSセレクタは右から左に向かって処理されます。
ここで言うマッチングとは、「どのHTMLタグにどのCSSのスタイル(プロパティ)を付与するかの判定」を指します。
仮に下記のようなCSSセレクタがあったとしましょう。

table > tbody > tr > td {
...
}

下記のような流れで目的の要素を探します。
1. 要素名がtd
2. その親要素名がtr
3. その親要素名がtbody
4. その親要素名がtable
右から左に向かって処理される分、セレクタの記述を詳細にすればするほど処理は遅くなってしまいます。
下記のように記述するとすぐに目的の要素を見つけることができます。

<table>
<tbody>
<tr>
<td class="table__td"></td>
</tr>
</tbody>
</table>

.table__td {
...
}

とはいえ、全てのタグにクラス名をつけてマッチング判定を1回にするのはCSSの見通しが悪くなってしまいます。
なので「セレクタは3つまでにする」などのルールを設けてあげるといいかもしれません。

HTMLタグに直接スタイルをあてる

仮に下記のようなCSSセレクタがあったとしましょう。

.content p {
...
}

先程も記載しましたが、CSSのマッチングは右から左です。
下記の流れで目的の要素を探します。
1. HTML内のすべてのpタグを洗い出す
2. 1の中から.contentが親要素であるものを絞り出す
すべてのpタグが判定対象になってしまうため、レンダリング時間に影響が出てしまいます。
またHTMLタグに直接CSSをあてると、予期せぬ場面で必要のないスタイルがあたってしまうといったケースも多くあるので注意が必要です。

最後に

余談を挟んでしまいましたが、上記がFLOCSSの設計思想となっております。
「0からCSSを作るんだけどどっから始めたらいいかわからない」
そんな時はFLOCSSの思想を意識してCSSを構築していくといいかもしれません。
ということで、2021年も張り切っていきましょう〜〜!
以上、みーちゃんでした〜!

CSS
Fabeee編集部

Fabeee編集部

こちらの記事はFabeee編集部が執筆しております。