タイトル: classセレクタ
SEOタイトル: CSS class セレクタ完全ガイド(複数指定・BEM・Tailwind・classList)
| この記事の要点 |
|
class セレクタの基本
CSS で最もよく使うセレクタが class セレクタ。HTML 要素の class 属性で付けた名前にスタイルを適用します。
/* HTML: テキスト
*/
.note {
background: #fff8e1;
padding: 0.5em;
}
/* 要素 + class(p で class="note" のものだけ) */
p.note {
font-style: italic;
}
/* 子孫セレクタ(.card の中の .title) */
.card .title { font-size: 1.2em; }
/* 直接の子(.card 直下の .title だけ) */
.card > .title { color: red; }
/* 隣接兄弟(.heading の直後の .lead) */
.heading + .lead { margin-top: 0.5em; }
複数の class を組み合わせる
| セレクタ | 意味 | マッチ例 |
|---|---|---|
.a, .b | a または b(OR) | class="a" または class="b" |
.a.b | a かつ b(AND、スペース無し) | class="a b" |
.a .b | a の子孫の b(スペース有り) | |
.a > .b | a の直接の子の b | 1 階層下のみ |
.a + .b | a の直後の隣接兄弟 b | — |
.a ~ .b | a の同階層後続の b(複数可) | — |
:not(.a) | a クラスを持たない | — |
/* 例: btn-primary かつ btn-large にだけ適用 */
.btn-primary.btn-large {
padding: 1em 2em;
font-size: 1.25em;
}
/* btn か btn-link のどちらかなら hover */
.btn:hover, .btn-link:hover {
opacity: 0.8;
}
/* card の中の title (直下じゃなくてもよい) */
.card .title {
font-weight: bold;
}
class vs id(詳細度の違い)
| セレクタ | 詳細度 (Specificity) | 使用場面 |
|---|---|---|
要素 (p) | 0,0,0,1 | 初期化・全要素に共通 |
class (.cls) | 0,0,1,0 | ★ 通常はこれ |
属性 ([type=text]) | 0,0,1,0 | フォーム要素等 |
擬似クラス (:hover) | 0,0,1,0 | 状態 |
id (#id) | 0,1,0,0 | 1ページに1個。スタイル指定には非推奨 |
インライン (style=...) | 1,0,0,0 | 動的に変更する場合のみ |
| !important | 勝つ | 最終手段 |
id を CSS で使うと詳細度が高すぎてオーバーライドしにくく、再利用もできないため、スタイル用には class を、JS で要素を一意に取りたい時だけ id を使うのが定石です。
BEM 命名規則
BEM (Block, Element, Modifier) は大規模 CSS の衝突回避でデファクトになった命名規則:
タイトル
本文
.card { /* Block */ }
.card__image { /* Element */ }
.card__title { /* Element */ }
.card__btn { /* Element */ }
.card__btn--primary { /* Modifier */
background: blue;
color: white;
}
.card--dark { /* Block Modifier */
background: #222;
color: white;
}
BEM の利点: 詳細度が常に「class 1個分」で揃う / グローバル衝突しにくい / 命名から要素関係が読める。
Tailwind CSS(ユーティリティクラス)
BEM とは逆方向のアプローチ。「意味のあるクラス名を作らず、見た目を class で組み立てる」:
Tailwind の長所: CSS ファイルを書かなくて済む、未使用 CSS をビルド時に削除(PurgeCSS)、デザインシステムが強制される。短所: クラスが冗長、HTML の見通しが悪くなる → @apply や Vue/React のコンポーネント化で緩和。
jQuery と class セレクタ
// jQuery: CSS と同じセレクタが使える
$('.note').css('color', 'red');
$('.btn-primary.btn-large').on('click', handler);
$('.card .title').text('新しいタイトル');
// Vanilla DOM API(同等)
document.querySelectorAll('.note').forEach(el => el.style.color = 'red');
document.querySelector('.btn-primary.btn-large').addEventListener('click', handler);
JS からの class 操作: classList API
const el = document.querySelector('.menu');
// 追加 / 削除 / トグル
el.classList.add('active');
el.classList.remove('hidden');
el.classList.toggle('open'); // ある→無くす、無い→付ける
el.classList.toggle('open', someBool); // 第2引数で強制 true/false
// 存在チェック
if (el.classList.contains('active')) { ... }
// 置換
el.classList.replace('old', 'new');
// 複数同時
el.classList.add('a', 'b', 'c');
el.classList.remove('a', 'b');
// 旧 API(避ける) - 文字列の連結だとミスりやすい
el.className = el.className + ' active'; // ❌
// 配列として全 class を取得
console.log([...el.classList]); // ['menu', 'active']
命名の落とし穴と推奨ルール
- 数字始まりはNG:
.2col❌ →.col-2✅(CSS パーサが解釈できない) - 大文字・小文字を混在させない: BEM は kebab-case、JS は camelCase を分ける
- 状態は
is-/has-プレフィックスを推奨:.is-active,.has-error - JS フック専用は
js-プレフィックス:.js-modal-toggle→ CSS では使わない - マルチバイト文字(
.メニュー)は仕様上可だが避ける - id と同じ名前は避ける: 詳細度の混乱を招く
CSS Modules / CSS-in-JS
近年の React/Vue では、グローバル class 名汚染を防ぐためスコープ付きの仕組みが主流:
// CSS Modules (Next.js 等)
import styles from './Card.module.css';
// → 自動で「Card_card__a1b2c3」のようなユニーク class に
export const Card = () => ...;
// CSS-in-JS (styled-components)
const StyledCard = styled.div`
padding: 1em;
background: white;
`;
// → DOM では .sc-bXY1Z2 のようなランダム class
FAQ
Q: 1 つの要素に class を何個まで付けられる?
A: 仕様上の上限なし。ただし可読性とパフォーマンスのため10 個以内を目安に。Tailwind で 30 個以上は @apply / コンポーネント化を検討。
Q: . はなぜクラスの記号?
A: CSS 仕様で「class 属性のドット記法」として定められたため。HTML 側にドットは含めず class="btn" のように書きます。
Q: class セレクタと属性セレクタ [class="btn"] の違い?
A: .btn は「class に btn を含む」、[class="btn"] は「class が完全一致 btn のみ」。複数 class を持つ要素では後者はマッチしません。[class~="btn"] なら .btn と同義。