大規模なWebサイトやアプリケーションのCSS管理で困っていませんか? セレクタの依存関係が複雑になり、新しい機能の追加が怖い…。スタイルの影響範囲が把握できない…。そんな悩みを抱える開発者は少なくありません。
FLOCSSは、これらの課題を解決する日本生まれのCSS設計手法です。レイヤー構造による明確な役割分担と、シンプルな命名規則により、チーム開発でも破綻しにくい設計を実現します。
この記事では、FLOCSSの基本から実践的な活用方法まで、具体的なコード例を交えて解説します。あなたのプロジェクトで、より保守性の高いCSSを書けるようになりましょう。
FLOCSSの基本概念
FLOCSSは「Foundation」「Layout」「Object」という3つの大きなレイヤーでCSSを設計・管理する手法です。
他のCSS設計手法との違い
CSS
/* OOCSS */
.button { }
.button-primary { }
/* BEM */
.button__icon { }
.button--large { }
/* FLOCSS */
.c-button { /* Component */
/* カスケード層を使用した詳細度制御 */
@layer component {
padding: 1rem 2rem;
border-radius: 0.5rem;
}
}
.p-header__button { /* Project */
@layer project {
/* コンテナクエリを使用したレスポンシブ対応 */
container-type: inline-size;
}
}
.u-mb10 { /* Utility */
@layer utility {
margin-block-end: var(--space-10);
}
}
FLOCSSの特徴:
- レイヤー構造による明確な役割分担
- BEMの命名規則を基本としながら、より柔軟な運用が可能
- 日本のWeb開発現場に適した設計思想
- カスケード層との相性が良く、詳細度の管理が容易
レイヤー構成
Foundation
ブラウザのデフォルトスタイルのリセットや、プロジェクト全体のベーススタイルを定義。
CSS
@layer foundation {
:root {
--color-primary: #0077cc;
--space-unit: 0.5rem;
}
body {
font-family: system-ui;
line-height: 1.5;
}
}
Layout
ヘッダーやメインコンテンツなど、サイトの骨格となるレイアウトを定義。
CSS
@layer layout {
.l-header {
container: header / inline-size;
padding-block: var(--space-unit);
}
.l-main {
container: content / inline-size;
margin-inline: auto;
max-width: 1200px;
}
}
Object
- Component:再利用可能な最小単位のモジュール
- Project:特定のプロジェクトで使用する固有のパターン
- Utility:margin、paddingなどの調整用クラス
CSS
/* Component */
@layer component {
.c-button {
background: var(--color-primary);
border-radius: 4px;
color: white;
}
}
/* Project */
@layer project {
.p-articleCard {
display: grid;
gap: calc(var(--space-unit) * 2);
}
}
/* Utility */
@layer utility {
.u-mt-2 {
margin-block-start: calc(var(--space-unit) * 2);
}
}
命名規則
CSS
@layer foundation {
/* f- プレフィックスは不要 */
:root {
--color-primary: #0077cc;
}
}
@layer layout {
/* レイアウト接頭辞 */
.l-container {
max-width: 1200px;
}
.l-grid {
display: grid;
}
}
@layer component {
/* 汎用コンポーネント */
.c-button {
/* ブロック */
}
.c-button__icon {
/* エレメント */
}
.c-button--large {
/* モディファイア */
}
}
@layer project {
/* プロジェクト固有 */
.p-articleList {
/* ブロック */
}
.p-articleList__item {
/* エレメント */
}
.p-articleList--featured {
/* モディファイア */
}
}
@layer utility {
/* ユーティリティ */
.u-mt-4 {
margin-block-start: 1rem;
}
}
ディレクトリ構成
ディレクトリ構成
styles/
├── foundation/
│ ├── variables.css /* カスタムプロパティ */
│ ├── reset.css /* リセットCSS */
│ └── base.css /* ベーススタイル */
├── layout/
│ ├── header.css /* ヘッダー */
│ ├── footer.css /* フッター */
│ └── grid.css /* グリッドシステム */
├── object/
│ ├── component/
│ │ ├── button.css /* 汎用ボタン */
│ │ └── card.css /* 汎用カード */
│ ├── project/
│ │ ├── header-nav.css /* ヘッダーナビ */
│ │ └── news-card.css /* ニュースカード */
│ └── utility/
│ ├── margin.css /* マージン調整 */
│ └── text.css /* テキスト調整 */
└── index.css /* メインのCSS */
CSS
/* index.css */
@layer foundation {
@import url("foundation/variables.css");
@import url("foundation/reset.css");
@import url("foundation/base.css");
}
@layer layout {
@import url("layout/header.css");
@import url("layout/footer.css");
@import url("layout/grid.css");
}
@layer component {
@import url("object/component/button.css");
@import url("object/component/card.css");
}
@layer project {
@import url("object/project/header-nav.css");
@import url("object/project/news-card.css");
}
@layer utility {
@import url("object/utility/margin.css");
@import url("object/utility/text.css");
}
実装例
CSS
/* 基本的なカードコンポーネント */
@layer component {
.c-card {
border-radius: 8px;
padding: var(--space-4);
}
}
/* プロジェクト固有のニュースカード */
@layer project {
.p-newsCard {
container-type: inline-size;
display: grid;
gap: var(--space-4);
}
.p-newsCard__title {
font-size: var(--font-size-lg);
font-weight: bold;
}
.p-newsCard__content {
@container (min-width: 640px) {
display: grid;
grid-template-columns: 2fr 1fr;
}
}
}
/* レイアウトでの配置 */
@layer layout {
.l-newsSection {
display: grid;
gap: var(--space-8);
margin-block: var(--space-8);
}
}
/* ユーティリティでの調整 */
@layer utility {
.u-shadow {
box-shadow: var(--shadow-md);
}
}
このように、各レイヤーの役割を意識しながら、モダンなCSS機能を活用したコンポーネント設計が可能です。
プロジェクトへの導入
段階的な導入手順
CSS
/* 1. カスケード層の定義 */
@layer foundation, layout, component, project, utility;
/* 2. 既存のスタイルを整理 */
@layer foundation {
/* グローバルなリセットとベーススタイル */
}
/* 3. 新規コンポーネントをFLOCSS化 */
@layer component {
.c-newFeature {
/* 新機能から段階的に適用 */
}
}
チーム開発でのガイドライン
CSS
/* コメントで目的を明確に */
@layer project {
/* 商品一覧の表示用コンポーネント */
.p-productList {
container-type: inline-size;
}
}
/* コンポーネントの依存関係を明示 */
@layer component {
/* @require ./button.css */
.c-buttonGroup {
display: flex;
gap: var(--space-2);
}
}
レビューチェックポイント
- 適切なレイヤーに配置されているか
- 命名規則は守られているか
- 不要な詳細度の上昇がないか
- カスケード層の使用は適切か
よくある課題と解決策
レイヤー判断の迷い
CSS
/* 迷いやすいケース */
@layer component {
/* 汎用的なカード */
.c-card { }
}
@layer project {
/* 特定のページでのみ使用するカード */
.p-newsCard { }
}
コンポーネントの粒度
CSS
/* 良い例:単一責任の原則 */
@layer component {
.c-button {
/* ボタンの基本スタイルのみ */
}
}
/* 避けるべき例:責任が多すぎる */
@layer component {
.c-buttonWithIconAndDropdown {
/* 複数の機能を1つのコンポーネントに詰め込みすぎ */
}
}
破綻防止のルール
CSS
@layer project {
.p-feature {
/* containerクエリで独立性を保つ */
container-type: inline-size;
}
/* カスタムプロパティで変更に強い設計 */
.p-feature__heading {
color: var(--feature-heading-color, var(--color-primary));
}
}
まとめ – FLOCSSによる持続可能なCSS設計
レイヤーによる明確な責任分離
CSS
@layer foundation { /* ベース設定 */ }
@layer layout { /* 骨格部分 */ }
@layer component { /* 再利用可能なパーツ */ }
@layer project { /* プロジェクト固有の実装 */ }
@layer utility { /* 調整用クラス */ }
設計のポイント
CSS
/* 1. コンポーネントの独立性を保つ */
@layer component {
.c-button {
--button-color: var(--color-primary);
}
}
/* 2. インターフェースを明確に */
@layer project {
.p-header {
container-type: inline-size;
}
}
/* 3. 拡張性を確保 */
@layer utility {
.u-hidden {
display: none;
}
}
FLOCSSは単なるCSS設計手法ではなく、チーム開発を円滑にし、プロジェクトの持続的な成長を支える重要な基盤となります。モダンなCSS機能と組み合わせることで、より強力な設計パターンを実現できます。