【実務・中級編】 first-child擬似クラスの適用条件 – CSS実践ガイド

`:first-child`の「罠」と「本質」:中級者が陥るCSSセレクタの解像度

CSSを書き始めて数年、誰もが一度は「あれ、なんで効かないんだ?」と頭を抱えた経験があるはずだ。特に `:first-child` は、その名前の直感的な分かりやすさとは裏腹に、仕様の細部を理解していないと実務で痛い目を見る筆頭格のセレクタだ。

今日は、なぜ `:first-child` が時に期待を裏切るのか、そしてブラウザが裏側で一体どういう論理で要素を判定しているのかを紐解いていこう。

—

1. `:first-child` の定義を再定義する

多くのエンジニアが「親の中にある最初の要素」と解釈しているが、これは正確ではない。CSS仕様における `:first-child` の正確な定義はこうだ。

> 「親要素の最初の子要素」であり、かつ「指定したセレクタに合致するもの」

ここが決定的な分岐点になる。つまり、「親の最初の子」が、ターゲットにしているセレクタと一致しなければ、そのスタイルは一切適用されないということだ。

現場でよくある失敗パターン

警告:これは最初の要素(pタグ)

コンテンツ1
コンテンツ2

/ 「最初のdivを赤くしたい」と思って書くやつ /
.container div:first-child {
color: red;
}

このコード、実は何も変わらない。なぜなら、`.container` の最初の子要素は `p` タグだからだ。ブラウザは「よし、`div`を探すぞ。おっ、最初の子は……`p`か。じゃあ条件不一致、無視!」と処理している。これが `:first-child` のもっとも有名な「罠」だ。

—

2. ブラウザが裏側でやっていること

ブラウザのレンダリングエンジン(BlinkやWebKitなど)は、DOMツリーを構築する際、セレクタを「右から左」へ向かってマッチングする。

1. `div:first-child` というセレクタが来た。
2. 対象となる `div` 要素を見つける。
3. その `div` が「その親の最初の子であるか?」という条件(擬似クラスのフラグ)を即座にチェックする。
4. NOであれば、その `div` は候補から外れる。

この「遡り」の仕組みを知っておくと、複雑なセレクタを組む際にデバッグが劇的に速くなる。「なぜ効かないのか」ではなく「親の最初の子は何か?」を確認する癖をつけるだけで、CSSのトラブルシューティングは完結するんだ。

—

3. 実践:現場で使えるベストプラクティス

では、要素型が混在している環境で、どうやって「最初のdiv」を狙い撃ちすればいいのか?

解決策A:`:first-of-type` を使う(推奨)

もし「最初のdiv」だけを狙いたいなら、`:first-child` ではなく `:first-of-type` を使うのが正解だ。これは「その型(タグ)の中で最初のもの」を指す。

/ これなら親の最初がpであっても、divの中の最初の1つ目に適用される /
.container div:first-of-type {
background: #f0f0f0;
}

解決策B:あえて `:first-child` を使う場合

逆に、`p` タグが最初にあることを利用して、CSSでガードレールを敷くこともできる。

/ 最初の要素が特定の型である場合のみスタイルを当てる /
.container p:first-child {
font-weight: bold;
}

/ 最初の要素がdivじゃない場合にスタイルを当てたい、などの制御 /
.container > :first-child:not(p) {
border-top: 1px solid #ccc;
}

—

4. チーフアーキテクトからのアドバイス

実務において、過度に複雑なセレクタを繋げるのは避けるべきだ。特に `:first-child` を多用しすぎると、マークアップの順序が少し変わっただけでデザインが崩壊する、いわゆる「HTML依存度が高いCSS」が出来上がる。

僕がチームで推奨しているルールは以下の通りだ:

1. 基本はクラスに頼る: `:first-child` はあくまで「要素が動的に増えるリスト」などに限定する。
2. 構造が重要なら `:first-of-type`: 構造的に「最初の〇〇」を制御したいなら、迷わずこちらを使う。
3. セレクタを短く保つ: `div:first-child` と書くよりも、可能であれば `.item:first-child` のように、特定のクラスに対して適用するように設計する。これがCSS設計の「疎結合」というやつだ。

CSSは、魔法ではなく論理だ。ブラウザの気持ちになって「今、どの要素が親の最初の子として認識されているか?」を想像する。その視点さえ持てれば、もう君はCSSの挙動で迷うことはなくなるはずだ。

さあ、エディタに戻って、少しだけ意識的にセレクタを書いてみてほしい。その小さな積み重ねが、将来的に巨大なプロジェクトを支える堅牢なスタイルガイドへと繋がっていくはずだよ。

コメント

タイトルとURLをコピーしました