CSSの命名規則:BEM、OOCSS、SMACSSの比較
6 分で読了
CSSクラスの命名は些細なことに思えるかもしれませんが、大規模なコードベースでは最も重要な設計判断の一つになります。適切な命名規則は、詳細度の競合を防ぎ、名前の衝突を減らし、スタイルシートを自己文書化します。
CSSの命名が重要な理由
CSSはグローバル名前空間を持ちます。すべてのクラス名はどこからでもアクセス可能で、詳細度ルールがどのスタイルが適用されるかを決定します。命名規則がなければ、チームは必ず衝突を起こします。二人の開発者がともに.cardと名付け、一方が他方を上書きしてしまうのです。
BEM(Block Element Modifier)
BEMは最も広く採用されているCSS命名規則です。構造化されたパターンを使います:
.block {}
.block__element {}
.block--modifier {}
/* 例 */
.card {}
.card__title {}
.card__image {}
.card--featured {}
.card__title--large {}
BEMのルール
- ブロック:独立したコンポーネント。kebab-caseで命名:
.search-form、.nav-bar - エレメント:ブロックの一部で、単独では意味を持たない。ダブルアンダースコアで区切る:
.search-form__input - モディファイア:ブロック/エレメントのバリエーションや状態。ダブルハイフンで区切る:
.search-form--dark
BEMの利点
- 自己文書化:
.card__title--highlightedは何であるかが一目瞭然 - 低い詳細度:すべてが単一クラスセレクタ
- 名前の衝突なし:ブロック名がすべてをスコープ化
- フレームワーク非依存:どのテックスタックでも動作
OOCSS(オブジェクト指向CSS)
OOCSSは構造とスキン、コンテナとコンテンツを分離します:
/* 構造 */
.media { display: flex; align-items: start; }
.media__body { flex: 1; }
/* スキン */
.theme-dark { background: #333; color: #fff; }
.theme-light { background: #fff; color: #333; }
OOCSSは高い再利用性を持つユーティリティオブジェクトを作りますが、一つのHTML要素に多くのクラスが付くことがあります。
SMACSS(スケーラブルでモジュラーなアーキテクチャ)
SMACSSはCSSルールを5つのカテゴリに分類し、プレフィックスを使います:
| カテゴリ | プレフィックス | 例 |
|---|---|---|
| ベース | なし | html, body, h1 |
| レイアウト | l- | .l-sidebar |
| モジュール | なし | .card |
| ステート | is- | .is-active |
| テーマ | t- | .t-dark |
CSS ModulesとCSS-in-JS
Reactなどのモダンフレームワークはツールレベルで名前衝突を解決する代替手段を提供します:
- CSS Modules:クラス名を自動的にスコープ化。
.titleと書くと、ビルドツールが.Card_title_x7kd2を出力。JavaScriptのプロパティになるためcamelCaseを使用。 - Tailwind CSS:ユーティリティクラスを使用し、カスタム命名を完全に排除。
- styled-components / Emotion:自動生成クラス名を持つCSS-in-JS。
どれを選ぶべきか?
| アプローチ | 最適な用途 |
|---|---|
| BEM | 従来のCSS、多人数チーム、CMSテーマ |
| CSS Modules | React/Vue/Svelteのコンポーネントベースプロジェクト |
| Tailwind | ラピッドプロトタイピング、ユーティリティファーストのワークフロー |
| SMACSS | 整理が必要な大規模レガシーコードベース |
クラス名を変換する
CSSクラスは常にkebab-caseを使います。他の形式からの変換にはkebab-caseコンバーターをご利用ください。CSS Modules用のcamelCaseが必要な場合はcamelCaseコンバーターやケースコンバーターハブをお試しください。