CSS設計とは、クラス名の付け方とファイルの分け方にルールを決めて、あとから読んでも安全に直せるCSSを保つための考え方です。BEM・OOCSS・SMACSS・FLOCSSは、そのルールをまとめた代表的な4つの手法(設計記法)です。
この記事は「CSSは書けるけれど、気づくとレイアウトが崩れる」「どこを直せば良いか分からず !important を足してしまう」という段階の方に向けた入門記事です。専門用語は初めて出てきたところでかみ砕き、コード例はそのまま試せる短さにしています。
先に結論を書くと、最初に覚えるべきはBEM(クラス名の付け方のルール)です。そのうえでファイルが増えてきたらFLOCSSやSMACSS(ファイルの分け方のルール)を足す、という順番が一番迷いにくい進め方です。4つは競合するライバルではなく、役割が違うため組み合わせて使えます。
1. 設計なしのCSSで実際に起きること
CSS設計の必要性は、失敗例を見るのが一番わかりやすいです。次のコードは、ルールを決めずにCSSを書き足していったときによく起きる流れです。
/* トップページの見出し用に書いた */
.title {
font-size: 24px;
color: navy;
}
/* 数週間後、お知らせ一覧でも .title を使ったので小さくした
→ トップページの見出しまで小さくなってしまった */
.title {
font-size: 16px;
}
/* 原因を追うのが大変なので、とりあえず上書きで解決 */
.title {
font-size: 24px !important;
}この状態になると、次の3つの問題が同時に発生します。
- クラス名の衝突:
.titleや.boxのような一般的すぎる名前は、別のページ・別の担当者と必ずぶつかります。 - 影響範囲が読めない:1行直すと、どこが変わるのか分からないため、直すこと自体が怖くなります。
!importantの連鎖:上書きのための上書きが増え、最終的に誰も触れないCSSになります。
CSS設計は、この3つを事前に防ぐための決めごとです。難しい技術を新しく覚えるのではなく、「名前の付け方」と「置き場所」を最初に決めておくだけと考えて問題ありません。
2. CSS設計とは? 4つの手法の位置づけ
CSS設計の目的は、次の3つに集約されます。
- 一貫性:誰が書いても同じ形になり、読む側が迷わない
- 衝突の回避:クラス名が重複して意図しない場所が崩れるのを防ぐ
- 変更しやすさ:あとから機能を足すとき、影響範囲を限定できる
ここで初心者がつまずきやすいのが、「BEM・OOCSS・SMACSS・FLOCSSのどれを選べばいいのか」という問いです。実はこの4つは担当している範囲が違うため、どれか1つを選ぶ必要はありません。役割で並べると次のように整理できます。
| 手法 | 担当する範囲 | ひとことで言うと |
|---|---|---|
| BEM | クラス名の付け方 | 名前を見れば構造が分かるようにする |
| OOCSS | スタイルの考え方 | 使い回せる部品としてCSSを書く |
| SMACSS | CSSの分類 | 役割ごとに5つのカテゴリに仕分ける |
| FLOCSS | CSSの分類+ファイル構成 | 3層に分けてディレクトリまで決める |
実務でよくある組み合わせは「クラス名はBEM、ファイル構成はFLOCSS」です。名前のルールと置き場所のルールは別物なので、両方を同時に採用できます。
3. BEM(Block・Element・Modifier)
BEMは、クラス名を「かたまり・部品・状態」の3つに分けて書く命名規則です。ロシアのYandex社で生まれた手法で、現在もっとも広く使われています。
BEMの3つのパーツ
- Block(ブロック):単体で成り立つかたまり。例:カード、検索フォーム、ヘッダー
- Element(エレメント):ブロックの中でしか意味を持たない部品。例:カードのタイトル、カードのボタン
- Modifier(モディファイア):見た目や状態の違い。例:色違いのボタン、大きいサイズのカード
この3つを、アンダースコア2つとハイフン2つでつなぎます。区切り文字が2つ重なっているのは、単語区切りのハイフン1つ(例:news-list)と見分けるためです。
block__element--modifierBEMの具体例
カード(block)の中に、タイトル・本文・ボタン(element)があり、ボタンだけ色違いにする(modifier)例です。
<div class="card">
<h2 class="card__title">カードタイトル</h2>
<p class="card__text">カードの本文です。</p>
<button class="card__button card__button--primary">クリック</button>
</div>.card {
border: 1px solid #ccc;
padding: 20px;
}
.card__title {
font-size: 18px;
color: #333;
}
/* 共通の見た目はここに書く */
.card__button {
background-color: gray;
color: white;
}
/* 差分だけを modifier に書く(上書きが1行で済む) */
.card__button--primary {
background-color: blue;
}ポイントは、modifierに「変わる部分だけ」を書くことです。card__button--primary に色以外のスタイルまで書いてしまうと、共通部分の修正が2か所に分かれてしまいます。
BEMのメリットとデメリット
| メリット | デメリット |
|---|---|
| クラス名を見るだけで所属と役割が分かる | クラス名が長くなりやすい |
| 名前が固有になるので衝突しにくい | HTMLの記述量が増える |
| CSS側の入れ子が浅くなり、上書き事故が減る | ブロックの区切り方に慣れが必要 |
初心者がつまずきやすい点
もっとも多い誤解は、HTMLの入れ子と同じだけクラス名を深くしてしまうことです。BEMのelementは何段深くても1段で書きます。
/* NG:HTMLの階層をそのままつなげてしまう */
.card__list__item__link { }
/* OK:ブロックからの1段で表す */
.card__link { }
/* 深くなりすぎたら、別のブロックとして切り出す */
.card-list { }
.card-list__item { }4. OOCSS(Object Oriented CSS)
OOCSSは、CSSを「使い回せる部品」として書くための考え方です。命名規則そのものではなく、スタイルの分け方の原則を示している点がBEMとの違いです。原則は次の2つです。
OOCSSの2つの原則
- 構造(structure)と見た目(skin)を分ける:余白や枠線などの骨組みと、色や影などの装飾を別のクラスにする
- 入れ物(container)と中身(content)を分ける:「サイドバーの中にあるボタン」ではなく「ボタン」として書き、置き場所に依存させない
OOCSSの具体例
まず、原則を守らないとどうなるかを見てみます。
/* NG:置き場所に依存している
→ 同じボタンをフッターで使うと、また書き直しになる */
.sidebar .button {
padding: 12px 24px;
border-radius: 4px;
background-color: blue;
color: white;
}これを、骨組みと装飾に分けて書き直します。
<button class="button button-primary">送信する</button>
<button class="button button-ghost">キャンセル</button>/* 構造:どこに置いても変わらない骨組み */
.button {
display: inline-block;
padding: 12px 24px;
border-radius: 4px;
}
/* 見た目:色だけを担当する */
.button-primary {
background-color: blue;
color: white;
}
.button-ghost {
background-color: transparent;
color: blue;
}骨組みを1か所にまとめたので、余白を変えたいときは .button だけを直せば済みます。色のパターンが増えても、追加するのは数行のクラスだけです。
OOCSSのメリットとデメリット
| メリット | デメリット |
|---|---|
| 同じ部品をサイト全体で使い回せる | どこまで分割するかの判断が必要 |
| 共通部分の修正が1か所で済む | HTMLに書くクラスが増える |
| CSSの総量が増えにくい | 命名規則は別途決める必要がある |
なお、OOCSSは単体で使うというより、BEMやFLOCSSの中に取り込まれている前提の考え方と捉えると理解しやすくなります。
5. SMACSS(Scalable and Modular Architecture for CSS)
SMACSS(スマックス)は、CSSを役割ごとに5つのカテゴリへ仕分ける設計手法です。「このスタイルはどこに書けばいいのか」で迷わなくなるのが最大の利点です。
SMACSSの5カテゴリ
| カテゴリ | 書く内容 | 接頭辞の例 |
|---|---|---|
| Base | リセットCSSやタグそのものの初期スタイル | なし(body など) |
| Layout | ヘッダー・サイドバーなど大枠の配置 | l- |
| Module | ボタン・カードなど使い回す部品 | なし |
| State | 表示・非表示など状態の切り替え | is- |
| Theme | 配色変更などサイト全体の着せ替え | theme- |
SMACSSの具体例
/* Base:タグの初期状態 */
body {
margin: 0;
padding: 0;
}
/* Layout:大枠の配置には l- を付ける */
.l-header {
width: 100%;
background-color: #333;
}
/* Module:使い回す部品 */
.button {
background-color: blue;
color: white;
}
/* State:状態は is- で表す(JSから付け外しする) */
.is-hidden {
display: none;
}
/* Theme:着せ替え */
.theme-dark .button {
background-color: black;
}接頭辞(l- や is-)が付いていると、クラス名を見た瞬間に「これはレイアウト用」「これは状態用」と判断できます。この考え方は、次に紹介するFLOCSSにも引き継がれています。
SMACSSのメリットとデメリット
| メリット | デメリット |
|---|---|
| スタイルの置き場所が明確になる | 覚えるカテゴリが5つあり学習コストが高め |
| 大規模サイトでも破綻しにくい | ModuleとLayoutの線引きで迷いやすい |
状態管理(is-)の考え方が身につく | 小規模サイトには仕組みが大きすぎる |
6. FLOCSS(Foundation Layout Object CSS)
FLOCSS(フロックス)は、OOCSSやSMACSSの考え方を取り込んで日本で提案されたCSS設計手法です。名前は Foundation・Layout・Object の頭文字で、CSSを大きく3層に分けて管理します。国内の制作会社で採用例が多く、日本語のドキュメントが読めるのも初心者にはメリットです。
FLOCSSの3層構造
| 層 | 書く内容 | 接頭辞 |
|---|---|---|
| Foundation | リセットCSSや基本のタグスタイル | なし |
| Layout | ヘッダー・フッターなどページの大枠 | l- |
| Object | 使い回す部品すべて(3種類に細分化) | 下表を参照 |
FLOCSSの特徴は、部品にあたるObject層をさらに3つに分ける点です。ここが理解できればFLOCSSはほぼ理解できたといえます。
| Objectの種類 | 役割 | 接頭辞 | 例 |
|---|---|---|---|
| Component | 最小単位の部品。それ以上分けられないもの | c- | ボタン、ラベル |
| Project | そのサイト固有のまとまり | p- | 記事カード、お問い合わせフォーム |
| Utility | 余白や文字寄せなど微調整用 | u- | u-mt-8、u-text-center |
FLOCSSの具体例
/* Foundation:土台 */
html, body {
margin: 0;
padding: 0;
}
/* Layout:ページの大枠 */
.l-container {
display: flex;
justify-content: center;
}
/* Object / Component:最小単位の部品 */
.c-button {
display: inline-block;
padding: 12px 24px;
background-color: blue;
color: white;
}
.c-button--large {
padding: 20px;
font-size: 16px;
}
/* Object / Project:このサイト固有のまとまり */
.p-article-card {
border: 1px solid #ccc;
padding: 20px;
}
/* Object / Utility:微調整だけを担当 */
.u-text-center {
text-align: center;
}ファイルもこの区分どおりに分け、foundation → layout → object の順に読み込みます。あとから読み込まれたCSSが優先されるという性質を利用して、土台から細かい調整へと段階的に上書きしていく形です。
FLOCSSのメリットとデメリット
| メリット | デメリット |
|---|---|
| ファイルの置き場所まで決まるので迷わない | 小規模サイトには構成が過剰になりやすい |
| 接頭辞でクラスの役割が一目で分かる | ComponentとProjectの線引きで迷いやすい |
| 日本語の資料が多く、チームで共有しやすい | 層を正しく保つ運用ルールが必要 |
ComponentとProjectで迷ったときは、「他のサイトにそのまま持っていけるならComponent、このサイト専用ならProject」という基準で判断すると整理しやすくなります。
7. 4つの手法の比較と、どれから始めるか
| 手法 | 役割 | 覚える量 | 向いている規模 | つまずきやすい点 |
|---|---|---|---|---|
| BEM | クラス名の付け方 | 少ない | 小〜大(すべて) | クラス名を深くしすぎる |
| OOCSS | スタイルの考え方 | 少ない | 再利用を重視する場面 | 分割の粒度が決まらない |
| SMACSS | CSSを5分類 | 多い | 中〜大規模 | LayoutとModuleの線引き |
| FLOCSS | 3層+ファイル構成 | 中くらい | 中〜大規模 | ComponentとProjectの線引き |
初心者が最初から全部を導入する必要はありません。次の3ステップで少しずつ広げるのが現実的です。
- BEMでクラス名を揃える:まずは
block__element--modifierの形に統一するだけで、衝突事故は大きく減ります。 - 状態を
is-で表す:is-open、is-activeのように、JavaScriptで切り替える部分を分離します。 - ファイルをFLOCSSの3層に分ける:CSSが1000行を超えたあたりが、ファイル分割を始める目安です。
もっとも避けたいのは、手法を決めないまま書き進めることです。完璧な手法を選ぶことよりも、1つのルールを最後まで守り切ることのほうが効果があります。
8. 慣れてきたら取り入れたい実務Tips
ここからは、チーム開発や中規模以上の案件で効いてくる実践的なポイントです。最初から全部やる必要はないので、必要になった段階で戻ってきてください。
ルールを1枚にまとめる
命名規則(BEM)、ファイル構成(FLOCSSの3層)、接頭辞の一覧をA4一枚にまとめておきます。口頭で共有したルールは必ず崩れるため、ドキュメント化しておくとレビューや新メンバーの参加がスムーズになります。
BEMは浅く短く保つ
block__elem--mod を基本に、入れ子は2段までを目安にします。セレクタを深くすると詳細度(Specificity=どのCSSが優先されるかの強さ)が上がり、あとから上書きしづらくなります。深くなってきたら、別のブロックとして切り出すのが正解です。
役割の分離を徹底する
見た目(skin)と構造(structure)を分けます。例えば card で骨組みを、is-elevated で影の有無を担当させると、装飾のバリエーションが増えても骨組み側を触らずに済みます。
カスケードレイヤで衝突を防ぐ
カスケードレイヤは、CSSの優先順位をレイヤ単位で固定できる比較的新しい仕組みです。次のように宣言しておくと、書いた順や詳細度に関係なく、後ろのレイヤが確実に勝ちます。
@layer reset, base, utilities, components, overrides;状態はクラスで表現する
is-active、is-disabled などの状態クラスは、JavaScriptから付け外しする前提で設計します。:hover や :focus-visible(キーボード操作時だけ表示される枠)と併用すると、アクセシビリティも確保できます。
色や余白はCSS変数にまとめる
色・余白・フォントサイズをCSS変数(カスタムプロパティ)として1か所に定義しておくと、サイト全体の調整が一括で行えます。ダークテーマへの対応も、変数の値を差し替えるだけで済みます。
:root {
--color-primary: #1a4fd6;
--space-2: 16px;
}
.c-button {
background-color: var(--color-primary);
padding: var(--space-2);
}ユーティリティは最小限にする
u-mt-8 や u-text-center のような微調整クラスは便利ですが、増やしすぎるとHTMLがクラスだらけになり可読性が落ちます。追加してよい条件をあらかじめ決めておきましょう。
ツールでルールを自動チェックする
StylelintとPrettierを導入すると、書式や記法の違反を自動で検出できます。人の目視だけに頼ると設計は必ず崩れるため、仕組みで守るのが確実です。
既存サイトへの導入は段階的に
すでに動いているサイトのCSSを一度に書き換えるのは危険です。「新しく作る部分は新ルール/既存は触る範囲だけ整える」という方針にし、旧CSSは legacy/ ディレクトリにまとめておくと、残作業が見える状態を保てます。
よくある質問(FAQ)
Q. BEMとは何ですか?
BEM(Block Element Modifier)はCSSの命名規則で、block__element–modifierの形式でクラス名を付けます。.card__title–largeのように、どのかたまりに属する何の部品なのかがクラス名から読み取れるのが特徴です。
Q. FLOCSSとは何ですか?
FLOCSS(フロックス)は日本で提案されたCSS設計手法で、Foundation・Layout・Objectの3層構造でスタイルを管理します。Object層はさらにComponent(c-)・Project(p-)・Utility(u-)に分かれ、大規模サイトの保守性を高めます。
Q. BEMとFLOCSSのどちらを使うべきですか?
BEMは命名規則、FLOCSSはファイル構成の設計手法なので、どちらか一方を選ぶものではなく組み合わせて使うのが一般的です。小規模サイトではBEMだけで十分ですが、複数人での開発や大規模プロジェクトではFLOCSSの層構造を導入すると管理しやすくなります。
Q. 個人開発の小さなサイトでもCSS設計は必要ですか?
必要です。ただし全部を導入する必要はなく、まずはBEMでクラス名を統一するだけで十分な効果があります。ページ数が少なくても、数か月後の自分が読み返すときに影響範囲が分かることが最大の利点です。
Q. どの手法から学ぶのがおすすめですか?
BEMから学ぶのがおすすめです。覚えるルールが命名規則の1つだけで、既存のプロジェクトにも部分的に導入できるためです。BEMに慣れてCSSファイルが増えてきた段階で、FLOCSSやSMACSSのファイル分割を検討すると無理がありません。
Q. Tailwind CSSを使う場合もCSS設計は必要ですか?
Tailwind CSSはユーティリティクラスをHTMLに直接書くため、クラス名の衝突は起こりにくくなります。ただし同じ見た目のパーツをどこまで共通化するかという判断は残るため、部品の切り出し方を決めるという意味でのCSS設計の考え方は引き続き役立ちます。
まとめ
CSS設計は、クラス名の衝突と !important の連鎖を防ぐための決めごとです。BEMは名前の付け方、OOCSSは部品化の考え方、SMACSSとFLOCSSは分類とファイル構成を担当しており、互いに競合しません。
まずはBEMでクラス名を統一し、状態を is- で表すところから始めてください。CSSが増えてきたらFLOCSSの3層でファイルを分ける、という順番であれば、途中で破綻せずに設計を育てられます。
参考(各手法の公式・一次情報)
