CSS設計(BEM / Utility)入門|破綻しないスタイル管理の考え方

はじめに

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-12mt-3 混在)

BEM と Utility の使い分け

観点BEMUtility
向いているコンポーネント中心の開発素早い実装、画面数が多い
可読性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併用」が現実的

投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です