はじめに
CSSは小規模なら直感的に書けますが、ページやコンポーネントが増えると一気に辛くなります。
- どこで定義されたCSSか分からない
- 変更したら別の画面が崩れる(副作用)
- クラス名が
box2/left/redのように増殖する - 詳細度(specificity)が上がりすぎて上書き地獄
この問題を避けるために重要なのが CSS設計 です。
本記事では、現場でも使われやすい2つの代表手法である
- BEM(Block Element Modifier)
- Utility(ユーティリティクラス設計)
を、初心者にも分かるように整理し、最後に 同じUIをBEM版 / Utility版で実装するハンズオン を用意します。
CSS設計とは?
CSS設計は一言でいうと、
「CSSを増やしても破綻しないルールを作ること」
です。
設計で解決したいこと
- 影響範囲が読める(安全に変更できる)
- 再利用できる(同じUIを何回も作らない)
- 命名が統一される(探しやすい)
- 上書きが最小化される(specificityを上げない)
BEMとは?(命名規則で破綻を防ぐ)
BEMは、クラス名を 構造化されたルールで付ける設計です。
BEMの基本
- Block:独立した部品(例:
card) - Element:Blockの内部要素(例:
card__title) - Modifier:状態・バリエーション(例:
card--featured)
命名例
block
block__element
block--modifier
例:カードコンポーネント
<article class="card card--featured">
<h2 class="card__title">タイトル</h2>
<p class="card__text">本文</p>
<a class="card__button" href="#">詳細</a>
</article>
- どのCSSがどの部品か分かりやすい
- スタイルの衝突が起きにくい
Utility設計とは?(小さいクラスを組み合わせる)
Utilityは、役割が1つの小さなクラス(単機能) を積み上げてUIを作る考え方です。
例:
.mt-16(margin-top 16px).p-12(padding 12px).text-sm(小さめ文字).bg-white(背景白)
Utilityのメリット
- HTMLを見れば見た目が想像できる
- 追加CSSが少なく済む
- コンポーネント化しなくても揃えやすい
注意点(デメリット)
- HTMLのclassが長くなりがち
- ルールがないと同義クラスが増殖する(例:
mt-12とmt-3混在)
BEM と Utility の使い分け
| 観点 | BEM | Utility |
|---|---|---|
| 向いている | コンポーネント中心の開発 | 素早い実装、画面数が多い |
| 可読性 | CSS/HTMLともに分かりやすい | HTMLが長くなる |
| 再利用 | 強い(部品として再利用) | 強い(クラスを使い回す) |
| 運用 | 命名がルール化される | ルールがないと崩れやすい |
実務では「どちらかだけ」ではなく、
- コンポーネントはBEM
- 余白やレイアウトの微調整はUtility
のように 併用が多いです。
【ハンズオン】同じUIをBEM版 / Utility版で作る
ゴール
「プロフィールカード」を2パターンで実装し、設計の違いを体感します。
フォルダ構成
css-architecture/
├─ bem.html
├─ utility.html
└─ styles.css
1) BEM版
bem.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS設計(BEM)ハンズオン</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body>
<article class="profile-card profile-card--featured">
<div class="profile-card__header">
<div class="profile-card__avatar" aria-hidden="true"></div>
<div class="profile-card__meta">
<h1 class="profile-card__name">Saigo</h1>
<p class="profile-card__role">Frontend / DevOps</p>
</div>
</div>
<p class="profile-card__bio">
CSS設計(BEM / Utility)の学習用プロフィールカードです。
</p>
<div class="profile-card__actions">
<a class="profile-card__button" href="#">フォロー</a>
<a class="profile-card__button profile-card__button--ghost" href="#">詳細</a>
</div>
</article>
</body>
</html>
styles.css(BEM用の部分)
/* ベース */
body {
margin: 0;
font-family: Arial, sans-serif;
background: #f7f7f7;
padding: 24px;
}
/* Block */
.profile-card {
max-width: 520px;
margin: 0 auto;
background: #fff;
border: 1px solid #e5e5e5;
border-radius: 12px;
padding: 16px;
}
/* Modifier */
.profile-card--featured {
border-width: 2px;
}
/* Elements */
.profile-card__header {
display: flex;
gap: 12px;
align-items: center;
}
.profile-card__avatar {
width: 56px;
height: 56px;
border-radius: 50%;
background: #ddd;
flex: 0 0 auto;
}
.profile-card__name {
margin: 0;
font-size: 20px;
}
.profile-card__role {
margin: 4px 0 0 0;
color: #666;
font-size: 14px;
}
.profile-card__bio {
margin: 12px 0 0 0;
color: #333;
font-size: 14px;
line-height: 1.7;
}
.profile-card__actions {
display: flex;
gap: 10px;
margin-top: 14px;
}
.profile-card__button {
display: inline-block;
padding: 10px 12px;
border-radius: 10px;
text-decoration: none;
border: 1px solid #ddd;
color: #111;
background: #fff;
}
.profile-card__button--ghost {
background: transparent;
}
BEM版のポイント
profile-cardの中で完結するので衝突しにくい__で要素が追えるので保守しやすい--で状態(featured/ghost)を表現できる
2) Utility版
utility.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>CSS設計(Utility)ハンズオン</title>
<link rel="stylesheet" href="styles.css" />
</head>
<body class="bg-gray p-24 font-sans">
<article class="mx-auto max-w-520 bg-white bd bd-1 r-12 p-16">
<div class="flex gap-12 items-center">
<div class="w-56 h-56 r-full bg-muted"></div>
<div>
<h1 class="m-0 text-20">Saigo</h1>
<p class="mt-4 m-0 text-14 text-muted">Frontend / DevOps</p>
</div>
</div>
<p class="mt-12 text-14 lh-17">
CSS設計(BEM / Utility)の学習用プロフィールカードです。
</p>
<div class="mt-14 flex gap-10">
<a class="btn" href="#">フォロー</a>
<a class="btn btn-ghost" href="#">詳細</a>
</div>
</article>
</body>
</html>
styles.css(Utility用の部分)
/* Utility: ベース */
.font-sans { font-family: Arial, sans-serif; }
.bg-gray { background: #f7f7f7; }
.bg-white { background: #fff; }
.bg-muted { background: #ddd; }
.text-muted { color: #666; }
.p-24 { padding: 24px; }
.p-16 { padding: 16px; }
.mx-auto { margin-left: auto; margin-right: auto; }
.max-w-520 { max-width: 520px; }
.bd { border-style: solid; border-color: #e5e5e5; }
.bd-1 { border-width: 1px; }
.r-12 { border-radius: 12px; }
.r-full { border-radius: 9999px; }
.w-56 { width: 56px; }
.h-56 { height: 56px; }
.flex { display: flex; }
.items-center { align-items: center; }
.gap-12 { gap: 12px; }
.gap-10 { gap: 10px; }
.m-0 { margin: 0; }
.mt-4 { margin-top: 4px; }
.mt-12 { margin-top: 12px; }
.mt-14 { margin-top: 14px; }
.text-20 { font-size: 20px; }
.text-14 { font-size: 14px; }
.lh-17 { line-height: 1.7; }
/* Utilityでも「ボタン」だけはコンポーネント化する例 */
.btn {
display: inline-block;
padding: 10px 12px;
border-radius: 10px;
text-decoration: none;
border: 1px solid #ddd;
color: #111;
background: #fff;
}
.btn-ghost {
background: transparent;
}
Utility版のポイント
- 追加CSSを増やさず、組み合わせでUIを作れる
- HTMLを見れば「余白/レイアウト/文字サイズ」が分かる
- ただし class が長くなるため、ルール設計が必須
SEOの観点でのCSS設計ポイント
CSS設計は直接の検索順位要因ではないですが、結果的にSEOに効きます。
- レイアウト崩れが減り UXが向上(離脱低下)
- 修正が安全になり 表示速度改善(無駄なCSS削減)
- 破綻しないことで モバイル対応品質が維持できる
どちらを選ぶべき?おすすめの現実解
初心者〜中級者におすすめの方針はこれです。
- 基本はBEMでコンポーネント設計
- 余白・レイアウトだけ Utilityで補助
idは原則使わず、class中心で運用- 詳細度を上げない(
!importantを乱用しない)
まとめ
本記事では CSS設計(BEM / Utility) を解説し、ハンズオンで違いを体験しました。
- BEM:部品単位で保守しやすく、衝突に強い
- Utility:素早く作れて、再利用しやすいがルール必須
- 実務では「BEM + Utility併用」が現実的
コメントを残す