疑似クラスとは
疑似クラスはコロンの後に書くキーワードで、文書内の 位置 や 状態 で要素を選択します。通常のセレクタに付けて使います: li:first-child、input:focus、a:hover。
リンクやマウスの状態を表す疑似クラス (:hover、:active、:visited) は CSS hover のページで解説しています。
:nth-child() と an+b の数式
:nth-child() には数値、キーワード、または an+b という数式を渡します。ブラウザは n = 0, 1, 2, ... と順に試し、数式が生む位置すべてに一致させます (位置は 1 から始まります)。
| 数式 | 一致する位置 | 意味 |
|---|---|---|
3 | 3 | 3 番目の子 |
odd または 2n+1 | 1, 3, 5, ... | 奇数行 |
even または 2n | 2, 4, 6, ... | 偶数行 |
3n | 3, 6, 9, ... | 3 つおき |
n+4 | 4, 5, 6, ... | 4 番目以降 |
-n+3 | 1, 2, 3 | 最初の 3 つ |
3n+1 | 1, 4, 7, ... | 最初から 3 つおき |
数式を入力して、どの項目が一致するか見てみましょう:
odd、even、4、n+7、-n+5、2n+3 を試してみてください。無効な数式は何にも一致しません。
後ろから数えるのが :nth-last-child() です。li:nth-last-child(-n+2) は最後の 2 項目を選択します。
nth-child と nth-of-type
:nth-child() はタグに関係なくすべての兄弟要素を数え、その後でセレクタの残りを確認します。:nth-of-type() は同じタグの兄弟だけを数えます。兄弟が混在すると、すぐに違いが出ます:
端についても同じ組み合わせがあります: :first-child / :first-of-type、:last-child / :last-of-type、:only-child / :only-of-type。
:not()、:is()、:where()
| 疑似クラス | 例 | 一致するもの |
|---|---|---|
:not(X) | li:not(.done) | X に一致しない要素 |
:is(X, Y) | :is(h1, h2, h3) a | リストのいずれかに一致する要素 |
:where(X, Y) | :where(ul, ol) li | :is() と同じで、詳細度はゼロ |
:has(X) | li:has(> input:checked) | X に一致するものを含む要素 |
毎日のように使うのは :not() です。たとえば項目の間に区切りを入れ、最後の項目の後には入れない場合です:
状態の疑似クラス: focus、checked、disabled、invalid
| 疑似クラス | 一致するもの |
|---|---|
:focus | キーボードまたはマウスでフォーカスされている要素 |
:focus-visible | フォーカスされていて、ブラウザがリングを表示すべきと判断したもの (ふつうはキーボードでのフォーカス) |
:focus-within | フォーカスされた要素を含む要素 |
:checked | チェックされたチェックボックス、ラジオボタン、選択された <option> |
:disabled / :enabled | 無効化されている (いない) フォームコントロール |
:required / :optional | required があるかないかの入力欄 |
:invalid / :valid | 値が検証に失敗した、または通った入力欄 |
:user-invalid | 無効な値で、かつユーザーが操作した後のもの |
:placeholder-shown | プレースホルダーを表示中の入力欄 |
:empty | 子を持たない要素 (テキストもなし) |
:target | URL の #fragment と id が一致する要素 |
メールアドレス欄をクリックすると、:focus-within によってラベルが青になります。メールアドレスではない文字を入力して欄から離れると、:user-invalid で枠線がオレンジ色になります。通常の :invalid だと、触る前から空の必須欄がオレンジ色になっていたはずです。
:focus で何をするにしても、フォーカスが見えるスタイルは残しましょう。代わりを用意せずにアウトラインを消すと、キーボードで操作する人は自分がどこにいるのかわからなくなります。
:has(): 親セレクタ
:has() は、要素が何を含むかで要素に一致させます。長年求められてきた「親セレクタ」で、現在の Chrome、Firefox、Safari で動きます。
もう一方のプランを選んでみてください。JavaScript なしで、カード全体がラジオボタンに追従します。
よくある間違い
- コロンの前にスペースを入れる。
li :first-childは「li の中の最初の子」という意味です。li:first-childと書きましょう。 p:nth-child(1)が「最初の p」だと思う。 意味は「最初の子、ただしそれが p の場合」です。最初の p には:first-of-typeを使います。- 0 から数える。 位置は 1 から始まります。
:nth-child(0)は何にも一致しません。 - フォーカスのアウトラインを消す。 代わりを用意しない
:focus { outline: none }はキーボード操作を壊します。 :と::を混同する。:beforeは疑似要素::beforeの古い書き方です。疑似クラスは常にコロン 1 つです。
よくある質問
CSS の疑似クラスとは何ですか?
コロンの後に書くキーワードで、名前ではなく状態や位置で要素を選択します。a:hover、li:first-child、input:focus などです。通常のセレクタに付け足して使い、ほとんどの疑似クラスは詳細度ではクラスと同じに数えられます (:where() はゼロ)。
CSS の nth-child はどう動きますか?
:nth-child(an+b) は、兄弟の中での位置が n = 0, 1, 2 と進めたときの a×n+b になる要素に一致します。位置は 1 から数えます。:nth-child(3) は 3 番目の子、:nth-child(odd) または 2n+1 は奇数番目すべて、:nth-child(n+4) は 4 番目以降です。
nth-child と nth-of-type の違いは何ですか?
:nth-child() はすべての兄弟要素を数え、その後でセレクタの残りを確認します。:nth-of-type() は同じ種類の要素の兄弟だけを数えます。h2 の後に段落が続くリストでは、p:nth-child(1) は何にも一致しませんが、p:nth-of-type(1) は最初の段落に一致します。
CSS の :not() はどう使いますか?
除外したいセレクタをかっこの中に書きます。li:not(.done) はクラス done を持たないすべてのリスト項目に一致します。リストも書けます: input:not([type="checkbox"], [type="radio"])。
疑似クラスと疑似要素の違いは何ですか?
疑似クラス (コロン 1 つ、:hover) は、ある状態にある既存の要素全体を選択します。疑似要素 (コロン 2 つ、::before) は、要素の一部分を対象にするか、生成コンテンツを作ります。