コンテンツにスキップ

FLOCSSへの適用

FLOCSSに、StrataCSSの原則を適用して拡張する方法を説明します。

FLOCSS公式ドキュメント

概要

FLOCSSを置き換えるのではなく、FLOCSSの運用を @layer 化します。

FLOCSSのCSS分類、プレフィックス(c- / p- / u-)はそのままです。
StrataCSSが関わるのは、その外側にあたるファイル構造と @layer の骨格です。

手法を分解して見る

適用の前に、FLOCSSを一度分解し、StrataCSSがどのように関与するかを確認します。

構成要素 FLOCSSでの内容 StrataCSSの原則関与
分類語彙 Foundation / Layout / Object(Component / Project / Utility) なし(改名不要)
階層構造 CSS分類の記述順・読み込み順による上書き @layer を適用
命名規則 プレフィックスと MindBEMding なし(関与しない)
スコープ (明確な影響範囲の軸は存在しない) 別途検討

主体をFLOCSSとし、StrataCSSを比較軸に置いた状態で拡張できるのは、 @layer の導入のみになります。

以下、実際に適用してみます。

@layer の適用(Layering)

FLOCSSの「Foundation → Layout → Object」という並びは、「後のものが前のものを上書きする」という概念的なレイヤー構造です。
FLOCSSでも「レイヤーの順序を前後させてはいけない」と規定しており、この構造をファイルの読み込み順と、詳細度の管理という「規律」で維持しています。

この並びを、FLOCSSの語彙のまま @layer で宣言します。

FLOCSSの語彙のままレイヤーを宣言
@layer foundation , layout , object.component , object.project , object.utility;

これだけで、読み込み順が崩れても、詳細度が競っても、Foundation が Object を侵食しない状態が仕様として保証されます。(規律で守っていたものを、ブラウザが守るようになります)

StrataCSSの標準名(basecomponents)への改名は不要です。
原則3(Aligning)が求めるのは「分類名・ディレクトリ名・レイヤー名の一致」であり、特定の名前ではありません。FLOCSSの語彙で3つが揃っていることが、ここでの「理想の姿」です。

続けて、各ディレクトリのCSSを、宣言した @layer に所属させます。ディレクトリ構成・クラス名・HTMLの読み込みは既存のままで、エントリファイルの書き換えだけで導入できます。

ディレクトリ構成(語彙保存型)
📁 styles/
├─ 📁 foundation/
├─ 📁 layout/
├─ 📁 object/
│  ├─ 📁 component/
│  ├─ 📁 project/
│  └─ 📁 utility/
└─ 📄 style.scss     # エントリファイル
CSS|style.css|※ネイティブCSS共通
@charset "utf-8";

/* レイヤーの宣言
-------------------------------------------------- */
@layer foundation , layout , object.component , object.project , object.utility;

/* 各ディレクトリの取り込み
-------------------------------------------------- */
@import "./foundation/index.css" layer(foundation);
@import "./layout/index.css" layer(layout);
@import "./object/component/index.css" layer(object.component);
@import "./object/project/index.css" layer(object.project);
@import "./object/utility/index.css" layer(object.utility);
SCSS|style.scss
@charset "utf-8";

@use "sass:meta";

/* レイヤーの宣言
-------------------------------------------------- */
@layer foundation , layout , object.component , object.project , object.utility;

/* 各ディレクトリの読み込み
-------------------------------------------------- */
@layer foundation {
    @include meta.load-css("./foundation/");
}
@layer layout {
    @include meta.load-css("./layout/");
}
@layer object.component {
    @include meta.load-css("./object/component/");
}
@layer object.project {
    @include meta.load-css("./object/project/");
}
@layer object.utility {
    @include meta.load-css("./object/utility/");
}

これで、正規のFLOCSSの構成・語彙・命名を保ったまま、上書き順が @layer の仕様で固定されます。

注意点|Utility と !important

Utilityのスタイルを確実に適用するために !important を併用する運用は、制作の現場で広く見られます(FLOCSS自体が規定しているものではありません)。

@layer の導入後は、この運用を見直せます。
object.utility は最後に宣言されたレイヤーのため、他レイヤーの通常宣言に対して、詳細度に関係なく優先されます。結果、詳細度対策としての !important は、そもそも不要になります。

一方で !important を使い続ける場合は注意が必要です。
レイヤーをまたぐ !important 同士はレイヤーの強弱が反転するため、複数のレイヤーで !important を使っていると、object.utility!important は最下位になります。

詳細は「@layer導入時の注意点」をご確認ください。

ページ固有CSSをスコープ分離したい場合

FLOCSS の Object/Project(p-)は、ページのコンテンツに相当する分類です。これを全ページ一括ではなく、ページ個別のスコープ(Pages)に分離したいと考えるかもしれません。

しかし、Object のCSSは、全ページに配信され再利用できることを前提とした分類です。そして、上書きの規則(Component → Project → Utility)で束ねられた分類でもあるため、Project だけを異なるスコープに抜くと Object の束が保てなくなります。
結果、CSSの管理ディレクトリの構造と @layer の設定の間にねじれが生じ、メンタルモデルが一致しなくなります。

これを自然な形で解消するには、フラットな構成へ寄せていく必要があります。

対応表(参照用)

対応をまとめると次のようになります。

FLOCSS レイヤー例(語彙一致) StrataCSS標準(参考)
Foundation foundation Base
Layout layout Layout
Object / Component object.component Components
Object / Project object.project Pages(※)
Object / Utility object.utility Utilities

※ FLOCSSはグローバル空間の中で設計されているため、ページ個別の概念を導入するには別途設計判断が必要です。詳細については前項を参照してください。

次のステップ

FLOCSSでは、語彙を保ったまま @layer 化する様子を見ました。
次のITCSSでは、階層構造そのものを @layer 化する様子を見ます。

ITCSSへの適用