Webデザインにおいて、特定の要素だけにスタイルを適用したい場面は非常に多く存在します。
例えば、リストの最初の項目だけ色を変えたり、最後の項目だけ余白を消したりする作業は頻繁に発生します。
CSSの疑似クラスである:first-childと:last-childを活用すれば、HTMLに余計なクラスを追加することなくスマートにデザインを実現できます。
2026年現在のモダンなフロントエンド開発においても、これらのセレクタは保守性の高いコードを書くための必須知識です。
本記事では、基本的な指定方法から、初心者が陥りやすい「スタイルが効かない」といったトラブルの解決策まで詳しく解説します。
first-childとlast-childの基本概念
CSSの疑似クラスとは、要素の特定の状態や構造上の位置に基づいてスタイルを適用するための仕組みです。
その中でも:first-childと:last-childは、親要素から見た「兄弟関係」の中での順番を指定するために使用されます。
これらを使うことで、HTML構造を汚さずに柔軟なスタイリングが可能になります。
:first-childの使い方
:first-childは、親要素内にある最初の子供である要素を選択します。
例えば、リスト形式のナビゲーションで最初の項目だけ左側の余白をゼロにしたい場合に非常に便利です。
/* リストの最初のアイテムだけ文字を赤くする */
li:first-child {
color: #ff0000;
font-weight: bold;
}
上記のコードを適用すると、<ul>や<ol>の中にある一番最初の<li>タグだけにスタイルが反映されます。
:last-childの使い方
:last-childは、親要素内にある最後の子供である要素を選択します。
境界線(ボーダー)をリストの間に引く際、最後の項目だけ線を消したいというケースでよく使われます。
/* リストの最後のアイテムだけ下線を消す */
li:last-child {
border-bottom: none;
}
このように記述することで、リストの末尾に不要な線が表示されるのを防ぎ、美しいレイアウトを維持できます。
実践的な活用シーンとメリット
疑似クラスを活用する最大のメリットは、HTML側に「last」や「first」といった専用のクラス名を記述しなくて済む点にあります。
CMS(コンテンツ管理システム)などで動的に生成されるリストの場合、HTMLを手動で書き換えるのは現実的ではありません。
CSS側で構造を判定させることで、運用の手間を大幅に削減できます。
ナビゲーションメニューの余白調整
横並びのナビゲーションメニューでは、項目間にマージンを設定することが一般的です。
しかし、単純にmargin-rightを設定すると、最後の項目の右側にも余白ができてしまい、全体のバランスが崩れます。
/* 全てのメニューに右余白を付ける */
.nav-item {
margin-right: 20px;
}
/* 最後のメニューだけ右余白を0にする */
.nav-item:last-child {
margin-right: 0;
}
この手法を用いれば、親要素の幅いっぱいにメニューをきれいに配置することができます。
ブログ記事一覧のボーダーデザイン
記事一覧ページで、各記事の間に区切り線を引くデザインも定番です。
一番上の記事の上、あるいは一番下の記事の下に余計な線が出ないように制御する必要があります。
:first-childを用いて最初の要素の上線を消すか、あるいは:last-childで最後の要素の下線を消すのが一般的な手法です。
「効かない」時の原因と解決策
初心者の方が最も直面しやすいのが、正しく記述したはずなのにスタイルが反映されないという問題です。
これには疑似クラス特有の「選択ルール」が関係しています。
代表的な失敗例とその対処法を確認しましょう。
原因1:指定した要素が「本当の」最初の子供ではない
もっとも多いミスは、要素のタイプだけを見て判断してしまうことです。
p:first-childというセレクタは、「pタグの中で一番最初のもの」という意味ではありません。
正しくは「親要素の最初の子供であり、かつそれがpタグであるもの」という意味になります。
<div class="container">
<h2>タイトル</h2>
<p>ここにはスタイルが当たりません</p>
<p>テキスト</p>
</div>
上記のHTMLに対してp:first-childを指定しても、最初の子供は<h2>であるため、スタイルは適用されません。
このような場合は、後述する:first-of-typeを使用するか、HTML構造を見直す必要があります。
原因2:セレクタの優先順位が低い
他の場所で定義されたCSSのスタイルが優先されている可能性もあります。
特に複雑なフレームワークを使用している場合、クラス指定による詳細度が疑似クラスよりも高くなっていることがあります。
デベロッパーツールで現在のスタイルを確認し、セレクタの記述をより具体的にすることで解決できます。
原因3:動的な要素挿入による影響
JavaScriptなどで要素を動的に追加・削除している場合、意図した要素が「最後」ではなくなっている場合があります。
ブラウザのインスペクターを使用して、レンダリング後のDOM構造が想定通りになっているかチェックしましょう。
first-of-type と last-of-type との使い分け
:first-childが効かない場合の救世主となるのが、:first-of-typeです。
これらは似ていますが、判定の基準が明確に異なります。
| 疑似クラス | 選択基準 |
|---|---|
| :first-child | 親要素の絶対的に最初の子供を選択する。 |
| :first-of-type | 親要素の中で、そのタグの種類として最初の要素を選択する。 |
先ほどの例で言えば、p:first-of-typeを使えば、<h2>が最初にあったとしても、その次にある最初の<p>タグを選択できます。
特定のタグに限定して順番をカウントしたい場合は、of-type系を使用するのが正解です。
nth-child による柔軟な指定
最初と最後だけでなく、2番目や「3つおき」といった指定には:nth-child()を使用します。
:first-childは:nth-child(1)と同じ意味を持ちます。
また、:last-childは最後から数える:nth-last-child(1)と同等です。
/* 奇数番目の要素だけ背景色を変える */
li:nth-child(odd) {
background-color: #f9f9f9;
}
/* 偶数番目の要素だけ背景色を変える */
li:nth-child(even) {
background-color: #eeeeee;
}
複雑な表(テーブル)のデザインや、グリッドレイアウトでの交互の色分けに非常に効果的です。
2026年のモダンなCSSにおける注意点
2026年現在、ブラウザの進化によりCSSの表現力は飛躍的に向上しています。
かつてはJavaScriptで判定していた複雑な構造も、CSSだけで完結できるようになりました。
:has() セレクタとの組み合わせ
最新のブラウザでは:has()セレクタが広く普及しています。
「特定の要素を最後に持つ親要素」といった、親方向へのスタイリングも可能になっています。
:last-childと組み合わせることで、「最後の要素が画像だった場合のみ、親の余白を調整する」といった高度な制御が可能です。
FlexboxやGridとの相性
モダンなレイアウト手法であるFlexboxやCSS Gridでは、gapプロパティが一般的になりました。
以前は:last-childを使ってmargin-right: 0;としていた作業の多くが、gapプロパティだけで解決できるようになっています。
ただし、ボーダーを引くデザインなど、依然として疑似クラスが必要なケースも多いため、状況に応じた使い分けが重要です。
まとめ
CSSの:first-childと:last-childは、Web制作において非常に汎用性の高い強力なツールです。
これらを適切に使いこなすことで、HTMLの構造をシンプルに保ちながら、精緻なデザインを実現できます。
もしスタイルが当たらないときは、要素の並び順やタグの種類を再確認し、必要に応じて:first-of-typeなどの代替案を検討してください。
基本をマスターした上で、:nth-childや最新の:has()セレクタと組み合わせ、より効率的でメンテナンス性の高いスタイリングを目指しましょう。
