普段何気なく使っているCSSのセレクタですが、実はかなり豊富なバリエーションがあります。
全てを暗記する必要はありませんが、どういった種類があるのかをざっくりとでも知っているのとそうでないのとでは、コーディングの効率やふとした時の表現力に差が生まれます。
CSS3(Selectors Level 3)で大幅に拡張されたセレクタは、Selectors Level 4でさらに進化し、:has()や:is()、:where()といった強力な新機能が追加されています。
2025年12月現在、これらの多くは主要ブラウザで利用可能になっていますので、ぜひ確認してみましょう。
基本セレクタ一覧
| パターン | 説明 |
|---|---|
* | すべての要素 |
E | E 要素 |
E:defined | 定義済みの E 要素(カスタム要素を含む) |
属性セレクタ一覧
| パターン | 説明 |
|---|---|
E.class | ”class” クラスを持つ E 要素 |
E#id | ”id” という ID を持つ E 要素 |
E[foo] | ”foo” 属性を持つ E 要素 |
E[foo="bar"] | ”foo” 属性の値が “bar” である E 要素 |
E[foo~="bar"] | class="a bar b" のように空白区切りの値の1つが “bar” である E 要素 |
E[foo^="bar"] | ”foo” 属性の値が “bar” から始まる E 要素 |
E[foo$="bar"] | ”foo” 属性の値が “bar” で終わる E 要素 |
E[foo*="bar"] | ”foo” 属性の値に “bar” という文字列を含む E 要素 |
E[foo|="en"] | ”foo” 属性の値が “en” と完全一致、または “en-” で始まる E 要素 |
属性セレクタの使用例
/* href が "https" で始まるリンク */a[href^="https"] { }
/* href が ".pdf" で終わるリンク */a[href$=".pdf"] { }
/* href に "example" を含むリンク */a[href*="example"] { }
/* lang が "en" または "en-US", "en-GB" などにマッチ */[lang|="en"] { }属性セレクタの大文字小文字を区別するかどうか
CSS Selectors Level 4 から、属性値のマッチングで大文字小文字を区別するかどうかを指定できるようになりました。
| パターン | 説明 |
|---|---|
E[foo="bar" i] | ”foo” 属性の値が “bar” である E 要素(大文字小文字を区別しない) |
E[foo="bar" s] | ”foo” 属性の値が “bar” である E 要素(大文字小文字を区別する) |
^=、$=、=などでも同様に指定できます。
/* iフラグ: 大文字小文字を区別しない */a[href$=".pdf" i] { /* .pdf, .PDF, .Pdf などすべてマッチ */}
/* sフラグ: 大文字小文字を区別する */a[href$=".pdf" s] { /* ".pdf"のみマッチ、".PDF"などはマッチしない */}修飾子i, sのブラウザサポート時期には差があるので注意しましょう。(MDNを参照してください。)
どちらの修飾子も指定していない場合は、HTMLでは大文字区別を区別します。(s指定時と同じ)
結合子
| パターン | 説明 |
|---|---|
E F | E 要素の子孫である F 要素 |
E > F | E 要素の子である F 要素 |
E + F | E 要素の直後に現れる F 要素 |
E ~ F | E 要素より後ろにある兄弟の F 要素すべて |
結合子の使用例
<div> <h2>見出し</h2> <p>テキスト1</p> <p>テキスト2</p> <p>テキスト3</p></div>/* h2 より後ろにあるすべての p(テキスト1, 2, 3すべて) */h2 ~ p { color: blue; }
/* h2 の直後の p のみ(テキスト1だけ) */h2 + p { text-decoration: line-through; }見出し
テキスト1
テキスト2
テキスト3
擬似要素
| パターン | 説明 |
|---|---|
E::before | E 要素の内容の前に content で挿入する仮想要素 |
E::after | E 要素の内容の後に content で挿入する仮想要素 |
E::first-line | E 要素の最初の1行 |
E::first-letter | E 要素の先頭文字(ドロップキャップなどに使用) |
E::selection | ユーザーが選択したテキスト部分 |
E::placeholder | input / textarea のプレースホルダーテキスト |
E::marker | リストのマーカー(• や番号部分) |
論理的組み合せ
| パターン | 説明 |
|---|---|
E:not(s1, s2, ...) | セレクタリスト s1, s2, ... のいずれにもマッチしない E 要素 |
E:is(s1, s2, ...) | セレクタリスト s1, s2, ... のいずれかにマッチする E 要素 |
E:where(s1, s2, ...) | セレクタリスト s1, s2, ... のいずれかにマッチする E 要素 (詳細度を0にする) |
E:has(rs1, rs2, ...) | 相対セレクタリスト rs1, rs2, ... のいずれかにマッチする子孫を持つ E 要素 |
CSS Selectors Level 4では、特に以下の強力なセレクタが追加されました。
:has()
従来のCSSでは子要素から親要素を選択することができませんでしたが、CSS Selectors Level 4 からは:has()を使用することで、特定の子要素や状態を持つ親要素を選択できるようになりました。
/* ulまたはolを含むul */ul:has(ul, ol) {}
/* 直下の子要素に hogeクラスを持つ要素があるdiv */div:has(> .hoge) {}2025年現在、主要モダンブラウザで利用可能です。
:is() と :where()
複数のセレクタをまとめて記述でき、コードの重複を減らせます。
/* 従来の書き方 */header ul,header ol,footer ul,footer ol {}
input:focus,textarea:focus,select:focus {}/* :is()を使った書き方 */:is(header, footer) :is(ul, ol) {}
:is(input, textarea, select):focus {}:is() と :where() の詳細度の違い:
:is(): 引数の中で最も詳細度が高いセレクタの詳細度を引き継ぎます。:where(): 常に詳細度が0になります。
/* :is()は最も高い詳細度(#idの詳細度)を持つ */:is(#id, .class, div) { }
/* :where()は常に詳細度0 */:where(#id, .class, div) { }2025年現在、主要モダンブラウザで利用可能です。
ツリー構造で指定する擬似クラス
| パターン | 説明 |
|---|---|
:root | 文書のルート要素(HTMLでは<html>) |
E:scope | スコープの基準となる E 要素(通常のCSSでは :root と同等。shadow ツリーでは :host と同等) |
E:empty | 子要素もテキストも持たない空の E 要素 |
E:first-child | 最初の子である E 要素 |
E:last-child | 最後の子である E 要素 |
E:only-child | 唯一の子である E 要素 |
E:first-of-type | 同じ型をもつ要素のうち最初の E 要素 |
E:last-of-type | 同じ型をもつ要素のうち最後の E 要素 |
E:only-of-type | 同じ型をもつ要素が他にない唯一の E 要素 |
E:nth-child(n) | n 番目の子である E 要素 |
E:nth-child(n of S) | セレクタ S にマッチする要素のうち n 番目 |
E:nth-last-child(n) | 後ろから数えて n 番目の子である E 要素 |
E:nth-last-child(n of S) | セレクタ S にマッチする要素のうち後ろから n 番目 |
E:nth-of-type(n) | 同じ型をもつ要素のうち n 番目にある E 要素 |
E:nth-last-of-type(n) | 同じ型をもつ要素のうち後ろから数えて n 番目にある E 要素 |
:nth-child() の書き方
/* 3番目の子要素 */li:nth-child(3) { }
/* 奇数番目(1, 3, 5...)*/li:nth-child(odd) { }
/* 偶数番目(2, 4, 6...)*/li:nth-child(even) { }
/* 3の倍数番目(3, 6, 9...)*/li:nth-child(3n) { }
/* 3番目以降(3, 4, 5...)*/li:nth-child(n + 3) { }
/* 最初の3つだけ(1, 2, 3)*/li:nth-child(-n + 3) { }:nth-child() と :nth-of-type() の違い
E:nth-child(n)は、E要素で、かつ、その親要素から見てn番目である要素を選択します。E:nth-of-type(n)は、その親要素に含まれるE要素の中でn番目を選択します。
:first-child と :first-of-type の違いも同様です。
<div> <h2>親から見て1番目 / h2タグ</h2> <p>親から見て2番目 / pタグの中で1番目</p> <p>親から見て3番目 / pタグの中で2番目</p></div>/* 親から見て2番目で、かつ p タグなら赤色に */p:nth-child(2) { color: blue; }
/* pタグの中で2番目のものを緑色に */p:nth-of-type(2) { color: green; }
/* p タグの中で最初のものなら打ち消し線をつける */p:first-of-type { text-decoration: line-through; }親から見て1番目 / h2タグ
親から見て2番目 / pタグの中で1番目
親から見て3番目 / pタグの中で2番目
:nth-of-type(n)は、classやidなどによる属性指定には対応していません。 ofを使う必要があります。
:nth-child() の of 構文
:nth-child(n of S)は、特定のセレクタ(S)にマッチする要素の中から n 番目を選択できます。
<ul> <li>リスト1</li> <li class="item">リスト2</li> <li class="item">リスト3</li></ul>/* .item の中で2番目 → "リスト3" が該当 */li:nth-child(2 of .item) {color: green;}- リスト1
- リスト2
- リスト3
リンクに関する擬似クラス
| パターン | 説明 |
|---|---|
E:link | 未訪問のハイパーリンクである E 要素 |
E:visited | 訪問済のハイパーリンクである E 要素 |
E:target | 現在のURLのフラグメント(#〜)と一致するidを持つ E 要素 |
E:scope | スコープの基準となる E 要素(shadow ツリーにおいては :host と同等。通常のCSSでは :root と同等) |
E:any-link | 訪問状態に関係なく、すべてのハイパーリンクである E 要素 |
表示状態に関する擬似クラス
| パターン | 説明 |
|---|---|
E:open / E:closed | 開いている / 閉じている状態の E 要素(<details>, <select>, <dialog> など) |
E:popover-open | ポップオーバーとして表示されている E 要素 |
E:modal | モーダルダイアログとして表示されている E 要素 |
E:fullscreen | フルスクリーン表示されている E 要素 |
E:picture-in-picture | ピクチャーインピクチャーモードで表示されている E 要素 |
ユーザーアクションに関する擬似クラス
| パターン | 説明 |
|---|---|
E:active | クリック中・タップ中の E 要素 |
E:hover | マウスホバー状態にある E 要素 |
E:focus | フォーカス状態にある E 要素 |
E:focus-within | 自身または子孫がフォーカスを持つ E 要素 |
E:focus-visible | キーボード操作などでフォーカスされた E 要素 |
フォーム入力に関する擬似クラス
| パターン | 説明 |
|---|---|
E:enabled / E:disabled | 有効状態 / 無効状態 の UI 要素である E |
E:checked / E:unchecked/ E:indeterminate | チェックされた / チェックされていない / 不定状態 の UI 要素 E (チェックボックスやラジオボタンなど) |
E:default | デフォルト状態のフォーム要素である E |
E:in-range / E:out-of-range | 範囲内 / 範囲外 の値を持つ E |
E:required / E:optional | 必須 / 任意 のフォーム要素である E |
E:placeholder-shown | プレースホルダーが表示されている E |
E:autofill | オートフィルされた E |
E:read-only / E:read-write | 読み取り専用 / 編集可能な E |
E:valid / E:invalid | 現在の入力値に対するバリデーションに成功している / 失敗している E |
E:user-valid / E:user-invalid | ユーザー操作後に入力値に対するバリデーションに成功した / 失敗した E |
:invalid と :user-invalid の違い
:invalidはページ読み込み時点から適用されるため、ユーザーが何も入力していない状態でもエラー表示になってしまいます。:user-invalidはユーザーが実際に操作した後(入力してフォーカスを外した後)にのみ適用されます。
/* :invalid は初期状態から赤くなってしまうことがある */input:invalid { border-color: red;}
/* :user-invalid はユーザーが操作した後だけ赤くなる */input:user-invalid { border-color: red;}言語に関する疑似クラス
| パターン | 説明 |
|---|---|
E:lang(LANG) | 言語情報 “LANG” を持つ E 要素 |
E:dir(ltr) / E:dir(rtl) | 文字の方向が左から右 / 右から左 の E 要素 |
MDNに記載されていた:langを使ってqタグの引用符を変更する例が参考になるので紹介しておきます。
This English quote has anestedquote inside.
この日本語の引用には内部に入れ子の引用があります。
q { quotes: "\\201C\"" "\\201D" "\\2018" "\\2019";}:lang(ja) q { quotes: "「" "」" "『" "』";}リソース状態に関する疑似クラス
| パターン | 説明 |
|---|---|
E:playing | 再生中のメディア要素 E |
E:paused | 一時停止中のメディア要素 E |
E:seeking | シーク中のメディア要素 E |
E:buffering | バッファリング中で再生を再開できないメディア要素 E |
E:stalled | データ受信に失敗して再生が止まっているメディア要素 E |
E:muted | ミュート状態のメディア要素 E |
E:volume-locked | 音量がプログラムで変更できないメディア要素 E |
2025年に覚えておきたい便利なセレクタ
最後に、2025年で使用可能な役立つセレクタをピックアップしておわります。
:has()- 親要素の選択が可能になり、CSSだけでできる表現が増えます。(ただし、処理負荷が高いため、使いすぎには注意が必要です。):where()- セレクタの重複を減らしつつ、詳細度の管理にも使えます。(@layerの導入も考えてみてください。):focus-visible- キーボード操作時のスタイルを定義できるので、アクセシビリティ向上に役立ちます。:user-valid、:user-invalid- ユーザー操作後のバリデーション状態をフィードバックするのに役立ちます。E[foo^="bar"]、E[foo$="bar"]、E[foo*="bar"]- 属性値の部分一致も覚えておくと、より柔軟なスタイリングが可能になります。