6.

CSS疑似クラスまとめ|:hover・:nth-child・:not・:is・:has

編集
この記事の要点
  • 疑似クラス (pseudo-class) は要素の状態や位置に基づいてスタイルを当てる CSS セレクタ
  • コロン 1 つで指定: a:hover / input:focus / li:first-child
  • 状態系: :hover / :focus / :active / :checked / :disabled
  • 位置系: :first-child / :nth-child(n) / :last-of-type
  • モダン: :is() / :where() / :has() — セレクタの組み立てを劇的に簡潔化

疑似クラスとは

疑似クラス (pseudo-class) は、要素の状態 (ホバー中 / フォーカス中など)文書ツリー上の位置 (最初の子 / n 番目) に基づいてスタイルを適用するための CSS セレクタです。HTML マークアップを変更せずに動的なスタイル変化を作れます。

基本構文

セレクタ:疑似クラス {
    プロパティ: 値;
}

a:hover {
    color: red;
}

input:focus {
    outline: 2px solid #4f46e5;
}

li:first-child {
    font-weight: bold;
}

コロンは1 つです。コロン 2 つ (::before など) は疑似要素で別物。

状態に関する疑似クラス

疑似クラス意味
:hoverマウスが乗っている
:focusフォーカスを持っている
:focus-visibleキーボード操作でフォーカスを持っている
:focus-within自身または子孫がフォーカスを持っている
:activeクリック / タップ中
:visited訪問済みリンク
:link未訪問リンク
:checkedチェック済みのチェックボックス / ラジオ
:disabled無効化されたフォーム要素
:enabled有効なフォーム要素
:required必須入力のフォーム要素
:invalid不正な値のフォーム要素
:valid適切な値のフォーム要素
:placeholder-shownプレースホルダ表示中 (未入力)
/* リンクの状態別スタイル (LVHA 順) */
a:link    { color: blue; }      /* 未訪問 */
a:visited { color: purple; }    /* 訪問済み */
a:hover   { color: red; }       /* ホバー */
a:active  { color: orange; }    /* クリック中 */

/* チェックされたチェックボックスの隣のラベル */
input:checked + label {
    color: green;
    font-weight: bold;
}

/* 未入力のフォーム要素にラベルを下に表示 (CSS のみフロートラベル) */
input:placeholder-shown + label {
    transform: translateY(0);
}

位置に関する疑似クラス (構造擬似クラス)

疑似クラス意味
:first-child親の最初の子
:last-child親の最後の子
:only-child親の唯一の子
:nth-child(n)n 番目の子
:nth-last-child(n)後ろから n 番目の子
:first-of-type同じ種類の要素の最初
:last-of-type同じ種類の要素の最後
:nth-of-type(n)同じ種類の n 番目
:only-of-type同じ種類の唯一の要素
:empty子要素もテキストも持たない
:root文書のルート (通常 html)
/* テーブルの偶数行 (ゼブラストライプ) */
tr:nth-child(even) {
    background: #f5f5f5;
}

/* 1, 4, 7... 3 ずつ */
li:nth-child(3n + 1) {
    color: red;
}

/* 最初の段落だけ大きく */
p:first-of-type {
    font-size: 1.2em;
}

/* 子要素が 1 個もない要素を隠す */
.message:empty {
    display: none;
}

nth-child(n) の式

マッチ
33 番目
odd奇数番目
even偶数番目
2n2, 4, 6, ... (= even)
2n + 11, 3, 5, ... (= odd)
3n3, 6, 9, ...
n + 33 番目以降すべて
-n + 3最初の 3 つ

否定・論理疑似クラス

:not()

/* .important 以外の li */
li:not(.important) {
    color: gray;
}

/* 複数の否定 */
button:not(.primary):not(.danger) {
    background: #eee;
}

:is() — セレクタリストの簡潔化

/* 従来 */
h1 .highlight,
h2 .highlight,
h3 .highlight {
    color: red;
}

/* :is() を使うと */
:is(h1, h2, h3) .highlight {
    color: red;
}

セレクタの詳細度は引数内で最も高いものになります。

:where() — 詳細度ゼロ

:where():is() と同じだが詳細度を 0 にカウントするため、デフォルトスタイル定義に最適。

/* 後から簡単に上書き可能なデフォルトスタイル */
:where(article, section) p {
    line-height: 1.7;
}

:has() — CSS の親セレクタ

CSS で長年待望されていた「子に〜がある親」を選ぶセレクタ。Chrome / Edge / Safari 対応 (2023〜)、Firefox も 121+ 対応。

/* img を持つ figure */
figure:has(img) {
    background: #f0f0f0;
}

/* チェックされた input を持つ label */
label:has(input:checked) {
    color: green;
    font-weight: bold;
}

/* 子に .error を持つカードを赤枠 */
.card:has(.error) {
    border-color: red;
}

/* 直接の子 a がない li を弱表示 */
nav li:not(:has(> a)) {
    opacity: 0.5;
}

その他の便利な疑似クラス

疑似クラス意味
:targetURL のフラグメント (#xxx) と一致する id を持つ要素
:lang(ja)指定言語の要素
:dir(rtl)右から左に書く言語
:defaultデフォルト要素 (form の submit ボタンなど)
:in-rangeinput の値が範囲内
:out-of-rangeinput の値が範囲外
:read-only読み取り専用の input
:read-write編集可能な input

疑似クラスと疑似要素の違い

項目疑似クラス疑似要素
コロン1 つ (:hover)2 つ (::before)
対象既存の要素の状態 / 位置要素の一部 / 仮想要素
:hover :nth-child::before ::first-line

FAQ

Q: :hover とタッチデバイスの相性
A: タッチデバイスでは hover が「タップ時の状態」になりがち。@media (hover: hover)ホバー可能なデバイスだけに適用するのがモダン。

Q: :focus:focus-visible どちらを使う?
A: :focus-visible はキーボード操作時のみ。マウスクリックで outline が出ないので見た目がスッキリ。アクセシビリティとデザインの両立に最適。

Q: :has() の詳細度は?
A: 引数内の最も高い詳細度になる。:has(.btn) は class 1 個分の詳細度。

関連

  • 疑似要素 (::before / ::after / ::placeholder など)
  • CSS セレクタ全般 (要素 / クラス / ID / 属性 / 子孫)
編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. タイプセレクタ
  2. ユニバーサルセレクタ
  3. クラスセレクタ
  4. IDセレクタ
  5. CSS属性セレクタで要素を絞り込む
  6. 疑似クラス

最近更新/作成されたページ