この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:12
ページ更新者:guest
更新日時:2026-06-11 07:07:02

タイトル: セレクタ
SEOタイトル: CSS セレクタ完全リファレンス

この記事の要点
  • CSS セレクタは HTML 要素にスタイルを適用する条件指定の構文
  • 基本: タイプ (p) / クラス (.foo) / ID (#bar) / ユニバーサル (*)
  • 結合子: 子孫 (空白) / 子 (>) / 隣接兄弟 (+) / 間接兄弟 (~)
  • 疑似クラス: :hover / :nth-child() / :not() / :is() / :where() / :has()
  • 優先度 (Specificity): インライン > ID > クラス/属性/疑似クラス > 要素/疑似要素。同点なら後勝ち

CSS セレクタとは

CSS セレクタは、スタイルを適用する対象の HTML 要素を指定するパターン文字列です。color: red; のような宣言を「どの要素に当てるか」を決める役割を担います。

/* セレクタ { 宣言 } */
p { color: red; }       /* すべての p 要素 */
.note { color: blue; }  /* class="note" の要素 */
#main { width: 800px; } /* id="main" の要素 */

基本セレクタ

セレクタ記法マッチ対象
タイプ (要素)pすべての

クラス.btnclass="btn" を含む要素
ID#headerid="header" の要素
ユニバーサル*すべての要素
属性[type="text"]type="text" の要素
グルーピングh1, h2, h3複数を同時指定(OR)

結合子 (Combinator)

/* 子孫: a の中の span すべて (深さ無制限) */
a span { color: red; }

/* 子: a の直下の span のみ */
a > span { color: red; }

/* 隣接兄弟: a の直後の span のみ */
a + span { color: red; }

/* 間接兄弟: a の後にある同階層 span すべて */
a ~ span { color: red; }
結合子意味
(空白)子孫article p
>直接の子ul > li
+直後の兄弟h2 + p
~あとに続く兄弟全部h2 ~ p

属性セレクタ

[type]              /* type 属性を持つ */
[type="text"]       /* 完全一致 */
[class~="warning"]  /* 空白区切りで warning を含む */
[lang|="en"]        /* en または en-US 等 */
[href^="https://"]  /* https:// で始まる */
[href$=".pdf"]      /* .pdf で終わる */
[href*="github"]    /* github を含む */
[href*="GITHUB" i]  /* 大文字小文字無視 (i フラグ) */

疑似クラス (Pseudo-class)

状態系

a:link    { color: blue; }    /* 未訪問 */
a:visited { color: purple; }  /* 訪問済 */
a:hover   { color: red; }     /* マウスホバー中 */
a:focus   { outline: 2px solid orange; }  /* キーボードフォーカス */
a:active  { color: green; }   /* クリック中 */

input:checked   { ... }   /* チェック中 */
input:disabled  { ... }   /* 無効 */
input:required  { ... }   /* 必須 */
input:invalid   { border-color: red; }  /* バリデーションエラー */

構造系

li:first-child    /* 親の最初の子 */
li:last-child     /* 親の最後の子 */
li:only-child     /* 兄弟なし */
li:nth-child(2)         /* 2番目 */
li:nth-child(odd)       /* 奇数番目 */
li:nth-child(even)      /* 偶数番目 */
li:nth-child(3n)        /* 3 の倍数 */
li:nth-child(3n+1)      /* 1, 4, 7, ... */
li:nth-of-type(2)       /* 同じタグの中で 2 番目 */
li:nth-last-child(1)    /* 末尾から 1 番目 */

p:empty          /* 中身が空 */
input:placeholder-shown  /* プレースホルダ表示中 */

関数系 (CSS 4)

/* :not() = 除外 */
p:not(.intro) { color: gray; }

/* :is() = グループ化 (詳細度は最大の引数) */
:is(h1, h2, h3) a { color: inherit; }
/* 旧式: h1 a, h2 a, h3 a { color: inherit; } と同等 */

/* :where() = :is() と同じだが詳細度 0 */
:where(h1, h2, h3) a { color: inherit; }

/* :has() = 親セレクタ (Chrome 105+, Safari 15.4+, Firefox 121+) */
article:has(> img) { border: 1px solid; }  /* img を直下に持つ article */
form:has(input:invalid) button { opacity: 0.5; }  /* 不正な input がある form の button */

疑似要素 (Pseudo-element)

p::before        { content: "★ "; }   /* 要素の前に挿入 */
p::after         { content: " ←"; }   /* 要素の後に挿入 */
p::first-line    { font-weight: bold; }  /* 最初の行 */
p::first-letter  { font-size: 2em; }     /* 最初の文字 (ドロップキャップ) */
input::placeholder { color: #999; }      /* placeholder スタイル */
::selection      { background: yellow; } /* 選択範囲 */
::marker         { color: red; }         /* リストマーカー (li の "・") */

記法の違い: 旧仕様 (CSS 2) では :before のようにコロン 1 つだったが、CSS 3 以降は疑似要素はコロン 2 つ (::) が標準。

優先度 (Specificity)

同じ要素に複数のルールが当たったとき、どの宣言が勝つかを決めるのが詳細度。(a, b, c, d) の 4 値で比較し、左から順に大きい方が勝ちます。

カラムカウント対象
a (インライン)style=""

b (ID)#foo#main → 1
c (クラス/属性/疑似クラス).foo, [type], :hover.btn:hover → 2
d (要素/疑似要素)div, ::beforep span::after → 3
/* 詳細度の例 */
* { ... }                    /* (0,0,0,0) */
p { ... }                    /* (0,0,0,1) */
p.intro { ... }              /* (0,0,1,1) */
#main p.intro { ... }        /* (0,1,1,1) */
#main p.intro:hover { ... }  /* (0,1,2,1) */
style="..." (HTML属性)        /* (1,0,0,0) */

/* !important は最強だが乱用厳禁 */
p { color: red !important; } /* これが勝つ */

同点なら後勝ち。CSS の読み込み順 = 上書き順なので、後から書いた方が適用されます。

:is() / :where() の詳細度トリック

/* :is() は引数中 最も詳細度の高いものを採用 */
:is(.a, #b) p { ... }   /* (0,1,0,1) = #b と同じ */

/* :where() は常に 0 → 上書きしやすい "弱い" セレクタ */
:where(article, section) p { color: gray; }  /* (0,0,0,1) */
article p.intro { color: blue; }              /* (0,0,1,2) で勝つ */

パフォーマンスの注意

  • 右から左に評価されるdiv p .foo は「.foo の祖先に p、その祖先に div」と評価
  • ユニバーサルセレクタ * や属性セレクタ [*] はマッチ候補が多くやや遅い
  • クラスを使うのがほぼ常に最速かつメンテしやすい
  • 過剰なネスト body div ul li a span は読みづらく詳細度も無駄に上がる

BEM などの命名規則

/* BEM: Block__Element--Modifier */
.card           { /* Block */ }
.card__title    { /* Element */ }
.card--featured { /* Modifier */ }

/* メリット:
 *  - 詳細度を一定 (常に 1 クラス) に保てる
 *  - 名前の衝突が起きにくい
 *  - ネストが要らない
 */

FAQ

Q: ID とクラス、どちらを使うべき?
A: スタイルは原則クラス。ID はページ内で 1 個しか使えない上、詳細度が高すぎて上書きしづらくなります。ID は #anchor リンクや JS の getElementById 用に取っておくのが定石。

Q: :has() はもう使える?
A: Chrome 105+, Safari 15.4+, Firefox 121+ で利用可。2024 年以降は実用域ですが、IE11 等のレガシー対応が必要なら避ける。

Q: !important はいつ使う?
A: 原則使わない。ユーティリティ CSS (Tailwind 等) の ! 修飾や、外部スクリプトが当てたスタイルを潰したい場合のみ。