CSSで「最初の要素だけ」「2番目の要素だけ」「奇数番目だけ」にスタイルを当てたいとき、:first-child や :nth-child() を使うことがあります。
ただ、これらのセレクタはHTMLの構造によって効き方が変わるため、「指定したつもりの要素に効かない」「なぜか全部にスタイルが当たる」といったミスが起こりやすいです。
CSSの順番指定でよく使う疑似クラスの違いと、初心者がつまずきやすいポイントを、実際のコード例とあわせて整理します。
よくあるミス①:a:first-childで全部に効いてしまう
CSSの順番指定でよくあるのが、「最初のリンクだけに効かせたい」と思って書いたセレクタが、複数の要素に効いてしまうケースです。
.test li a:first-childこの指定は、「.test 内にある li の中の a」を探し、その a が親要素の中で最初の子要素である場合に反応します。
つまり、「リスト全体の最初のa」ではなく、「それぞれのliの中で最初に置かれているa」を見ています。
<ul class="test">
<li><a href="#">ターゲット1</a></li>
<li><a href="#">ターゲット2</a></li>
<li><a href="#">ターゲット3</a></li>
</ul>このHTMLでは、それぞれの li の中で a が最初の子要素になっています。そのため、3つのリンクすべてが対象になります。
.test li:first-child aリスト全体の1番目だけを指定したい場合は、a ではなく li の順番を見る必要があります。
.test li:first-child a と書くことで、「1番目の li の中にある a」だけを指定できます。
よくあるミス②:スペース1つで意味が変わる
CSSセレクタでは、スペースにも意味があります。特に疑似クラスと組み合わせると、スペース1つで対象が大きく変わることがあります。
.test li :first-child ali の後にスペースがあるため、これは「li 自体」ではなく、「li の中にある何らかの要素」を探す指定になります。
この場合、li の中の最初の子要素を探し、さらにその中にある a を対象にする、という意味になります。
li > div > a一方で、li > a のように li の直下に a がある構造では、意図したように反応しないことがあります。
「li:first-child」と「li :first-child」は似ていますが、前者は li 自体を見ていて、後者は li の中の子要素を見ています。
nth-child と nth-of-type の違い
順番指定で特に混乱しやすいのが、:nth-child() と :nth-of-type() の違いです。
どちらも「n番目」を指定できますが、数え方が違います。
| セレクタ | 数え方 | 反応する条件 |
|---|---|---|
p:nth-child(3) | 親要素の中で3番目を見る | 3番目の要素が p なら反応 |
p:nth-of-type(3) | p だけを数えて3番目を見る | 3番目の p に反応 |
<div class="sample">
<h2>見出し</h2>
<p>1つ目のp</p>
<p>2つ目のp</p>
<p>3つ目のp</p>
</div>このHTMLでは、親要素 .sample の中で h2 が1番目、最初の p が2番目、次の p が3番目です。
.sample p:nth-child(3) {
color: red;
}p:nth-child(3) は「親の中で3番目の要素が p なら反応する」という意味です。この例では、2つ目の p が親の中で3番目なので対象になります。
.sample p:nth-of-type(3) {
color: red;
}p:nth-of-type(3) は、p だけを数えて3番目を対象にします。そのため、この例では「3つ目のp」に反応します。
迷ったときは、「親の中で何番目か」を見るのが nth-child、「同じタグの中で何番目か」を見るのが nth-of-type と考えると整理しやすいです。
順番指定でよく使う疑似クラス
ここからは、順番指定でよく使う疑似クラスを簡単に整理します。すべてを一度に覚える必要はありませんが、よく使うものだけでも知っておくとCSSの調整がしやすくなります。
| セレクタ | 意味 | 使いどころ |
|---|---|---|
:first-child | 親の中で最初の子要素 | 最初の項目だけ装飾する |
:first-of-type | 同じタグの中で最初 | 最初の段落だけ調整する |
:last-child | 親の中で最後の子要素 | 最後の項目だけ線を消す |
:last-of-type | 同じタグの中で最後 | 最後の同タグだけ調整する |
:nth-child(odd) | 奇数番目 | リストや表の交互背景 |
:nth-child(even) | 偶数番目 | リストや表の交互背景 |
:nth-last-child(n) | 下からn番目 | 最後から数えて指定する |
:not() と組み合わせた実用例
順番指定は、:not() と組み合わせると実用的に使いやすくなります。
たとえば、親要素の中で最初の子要素ではない段落に余白をつけたい場合は、次のように書けます。
main#main .article p:not(:first-child) {
margin-top: 5px;
}この指定では、.article 内の p のうち、親要素の最初の子要素ではないものに margin-top を指定しています。
記事本文の余白調整や、リストの区切り線など、「最初だけ」「最後だけ」を除外したい場面で使いやすい書き方です。
.list li:not(:last-child) {
border-bottom: 1px solid #ddd;
}この例では、最後の li 以外にだけ下線をつけています。メニューやカード一覧などでよく使える指定です。
なお、:is()、:where()、:has() などの疑似クラスもありますが、これらは順番指定とは少し目的が異なります。この記事では、まず :first-child、:nth-child()、:nth-of-type() の違いを押さえておけば十分です。
まとめ
CSSの順番指定は、セレクタの書き方だけを見ると似ているものが多く、最初は少し分かりにくく感じます。
:first-childは、親の中で最初の子要素を見ます。:nth-child()は、親の中で何番目かを見ます。:nth-of-type()は、同じタグの中で何番目かを見ます。- スペースの有無で、対象になる要素が変わります。
- 迷ったときは、HTMLの親子関係を確認すると整理しやすいです。
すべての疑似クラスを覚える必要はありません。まずは「何を数えているのか」を意識しながら、必要な場面で少しずつ使っていくのがおすすめです。

コメント