CSS設計の手法を調べると、ITCSSとFLOCSSという2つの名前に行き当たります。どちらも「CSSを秩序立てて管理する」ための考え方ですが、性質が少し違います。前回の記事で触れた :is() / :where() による詳細度設計は、実はこの2つの考え方をベースに、自分のプロジェクト用にハイブリッドした結果でした。この記事では、ITCSSとFLOCSSをそれぞれ整理したうえで、実際にどう組み合わせて運用しているかを紹介します。
ITCSS(Inverted Triangle CSS)とは
ITCSSは「逆三角形」を描くように、CSSを詳細度と影響範囲が徐々に狭まっていくレイヤーとして読み込む考え方です。ディレクトリ構造というより「CSSの読み込み順序の設計指針」に近いものです。
settings/ → グローバル変数、設定(出力されない)
tools/ → ミックスイン、関数(出力されない)
generic/ → リセット、normalize
elements/ → HTML要素の基本スタイル(h1, a, pなど)
objects/ → 装飾を持たない構造パターン(OOCSS的な骨組み)
components/ → 具体的なUIコンポーネント
utilities/ → ヘルパークラス(!importantも許容される最上位)ポイントは、上から下に向かって詳細度が単調増加していくべきという規律です。これによって「後から書いたCSSなのに、詳細度が低くて勝てない」というカスケードの事故を構造的に防ぎます。逆に言うと、ITCSSはこの規律さえ守れば、ファイルやフォルダの命名規則自体には強いこだわりがありません。
FLOCSS(Foundation Layout Object CSS)とは
FLOCSSは、OOCSS・BEM・SMACSSのいいとこ取りをした、日本発のCSS設計手法です。ITCSSが「詳細度の順序」という抽象的な指針なのに対して、FLOCSSはディレクトリ構造と命名規則まで含めた、より実装寄りの仕様になっています。
foundation/ → reset・base(リセット・ベースの下地)
layout/ → header・footer・containerなど配置のみ(l-)
object/
component/ → 再利用可能な最小パーツ(c-)
project/ → componentの集合・大きなブロック(p-)
utility/ → margin/padding/表示切替などの単機能クラス(u-)命名はフォルダの頭文字をそのままプレフィックスにし(l- c- p- u-)、Element/ModifierはBEM(MindBEMding)で管理します。ComponentとProjectの境目は「裸の人間がComponent、ネクタイや靴下を着てビジネスマンになったらProject」という比喩がわかりやすく、Componentが複数集まって意味を持つ単位やセクション規模のブロックはProjectに分類します。
2つを並べると見えてくること
ITCSSとFLOCSSを並べると、実はかなり対応関係があります。
| ITCSS | FLOCSS | 役割 |
|---|---|---|
| settings / tools | (概念なし) | 変数・mixin |
| generic / elements | foundation | リセット・下地 |
| objects | layout | 配置のための骨組み |
| components | object/component, object/project | UIパーツ |
| utilities | object/utility | 単機能クラス |
FLOCSSの object ディレクトリは、ITCSSでいう「objects〜components」のレンジを component / project の2段階に割って実装可能な粒度に落とし込んだもの、と捉えると理解しやすくなります。
詰まったポイント:色トークン系ファイルの置き場
実際に手を動かしてみて最初に迷ったのが、style-color-palette1.scss のような色のバリエーションを大量に定義したファイルの置き場でした。
このファイルがやっていることは、
- カラーパレットというデザイントークンに近い性質を持つ(settingsっぽい)
- 実際には
.is-white.is-blackのようなクラスとして出力される(componentやutilityっぽい) - 特定のコンポーネントに紐づくわけではなく、ボタンにもバッジにもボックスにも使われる横断的なもの(utilityっぽい)
という、3つの性質が混ざった状態でした。FLOCSSの object/component に置くにはコンポーネント単体に紐づかなすぎるし、object/utility に置くには「色」という装飾的な性質がOOCSS的な「構造と装飾の分離」という原則と少し噛み合わない。SMACSSの「Theme」カテゴリに寄せる手もありますが、FLOCSSにはThemeという概念自体が存在しません。
結局、このファイルは「コンポーネント側の --c-* カスタムプロパティに値を流し込む役割」と割り切り、ITCSSでいう components のレンジ(詳細度2〜3)に置くことで決着しました。「見た目のクラスを出力するが、コンポーネント自体は定義しない」というファイルは、置き場所に迷ったらコンポーネント側の詳細度レンジに合わせる、というのが今回得た経験則です。
たどり着いた6層構成
ITCSSの詳細度の規律と、FLOCSSのobject三分割の実装しやすさを両方取り入れて、最終的に次の6層構成に落ち着きました。
| レイヤー | プレフィックス | 役割 | 詳細度の目安 |
|---|---|---|---|
| settings | (なし) | 変数・トークン・mixin。CSSの実指定なし | — |
| foundations | .fd-* | リセット・下地(reset → settings → elements → primers) | 0〜1 |
| layouts | .ly-* | ページ構造(body > page > section > container > wrapper > item) | 1〜2 |
| components | .cm-* | ボタン・バッジ・カードなどのUIパーツ | 2〜3 |
| utilities | .ut-* | margin・displayなど単機能クラス | 3〜4 |
| trumps | (なし) | 緊急時の上書き。!importantを許容 | — |
settings は本来ITCSSの独立レイヤーですが、「実体を持たない(CSSを出力しない)」という性質上、ファイルの読み込み順序的に foundations の直前に置いておくと管理しやすいため、実運用上は foundations に含めて扱っています。
詳細度のレンジは、前回の記事で紹介した :is() / :where() の組み合わせで実セレクタとして固定しています。
/* components層: .theme-name + :is()内最大値 = 詳細度(0,2,0) */
.theme-name :is(.badge, .button) { /* 基本形 */ }
.theme-name :is(.badge, .button):where(.is-narrow) { /* バリアントは:where()で増やさない */ }
/* utilities層: .theme-name + :not([unutility]) + :is() = 詳細度(0,3,0) */
.theme-name:not([unutility]) :is(.m-1r, .m-1r_sp) { margin: calc(var(--⅝fem) * 1); }utilities層に付けている :not([unutility]) は、単に詳細度を1段階稼ぐためだけでなく、unutility という属性を要素に付与するだけでユーティリティクラス全体を一括無効化できる「エスケープハッチ」としても機能しています。FLOCSSにはこうした「ユーティリティそのものを止める」仕組みは標準で用意されていないので、独自に追加した部分です。
CSS詳細度を図解する:IDs・class・typeから :is() :where()まで
ITCSS・FLOCSSをそのまま使わなかった理由
最後に、なぜ素直にITCSSやFLOCSSをそのまま採用しなかったのかを整理しておきます。
- ITCSSをそのまま使わなかった理由な詳細度の規律としては優れているが、ディレクトリ構造や命名規則の指針がないため、複数人での運用や命名の一貫性を担保しづらい
- FLOCSSをそのまま使わなかった理由な実装の指針としては優れているが、Layout層とComponent層の詳細度の差が前提として明示されておらず、
:is()/:where()のような詳細度制御の仕組みと組み合わせる発想が元々の仕様には含まれていない
ITCSSの「詳細度は逆三角形で単調増加すべき」という規律をFLOCSSの実装構造に持ち込み、それを :is() / :where() というモダンCSSのセレクタ関数で物理的に強制する、というのが今回たどり着いた形です。
次の記事では、この :is() / :where() をはじめとした擬似クラス関数が、それぞれ詳細度にどう影響するのかを図解付きで整理します。:not() :has() も含めた一覧表があると、今回の記事で出てきた詳細度の数字の根拠がより追いやすくなるはずです。
関連記事
CSS詳細度を図解する:IDs・class・typeから :is() :where()まで
CSSで「何番目か」を指定する:nth系セレクタとクラスベース位置選択の完全ガイド
CSS Layersの使い方と注意点 - 実際に使って分かった問題点

