こんにちは!フロントエンド・アーキテクチャの現場を長年歩んできた者です。
日々のコーディング、本当にお疲れ様です。CSSって、最初は「お、思った通りに動いた!」と楽しくなる反面、少し複雑なレイアウトに入った途端、「あれ、なんでこの線が消えないんだ…?」とか「最後の要素だけ下パディングを消したいのに!」といった、細かなイライラにぶつかりがちですよね。
大丈夫ですよ、その悩み、世界中のすべてのWeb制作者が通る「通過儀礼」みたいなものですから安心してくだだい。
今日は、そんな日常のちょっとしたイライラを魔法のように解決してくれる、CSSの心強い味方「`:first-child`」と「`:last-child`」という2つの擬似クラスについて、現場の知見をたっぷり交えながら、優しく紐解いていきたいと思います。
—
1. そもそも「擬似クラス」って何だろう?
難しい専門用語は少し置いておいて、まずはイメージから入りましょう。
例えば、お気に入りの洋服屋さんで、綺麗に並べられたTシャツの棚を想像してみてください。
店員さんは、「一番手前(最初)のTシャツ」や「一番奥(最後)のTシャツ」に、特別なPOPをつけたり、少しレイアウトを変えたりしたくなりますよね。
CSSの世界でも同じです。「並んでいる兄弟たちの中で、一番最初の子」や「一番最後の子」にだけ、こっそり特別な装飾をしたいときがあります。
そういうときに、要素へ「あなたは一番最初だからね」「あなたは一番最後だからね」と目印をつけて、指定してあげる役割を持つのが「擬似クラス(ぎじクラス)」です。
その中でも、文字通り「最初(First)」と「最後(Last)」の子供(Child)を指定するのが、今回主役の二人というわけです。
—
2. `:first-child`(最初の子)の出番:しつこい境界線をスマートに消す
まずは `:first-child` から見ていきましょう。英語の直訳通り、「兄弟の中で、一番最初に生まれた子」を指し示します。
よくある現場のシチュエーションとして、リストタグ(`
- ` と `
- `)を使って、メニューの項目を縦に並べるデザインを考えてみてください。項目と項目の間に、区切り線(ボーダー)を引くのはよくある手法です。
こんな感じですね。
li {
border-top: 1px solid #ccc; / すべての項目の上に線を引く /
padding: 10px;
}これをそのままブラウザで見ると、どうなるでしょうか?
一番上の項目の「さらに上」にも、ピシッと境界線が入ってしまいます。一番上なのだから、その上の線は邪魔ですよね。消したい!ここで登場するのが `:first-child` です。
/ リストの「最初の子」だけ、上の境界線を消しちゃおう /
li:first-child {
border-top: none;
}「お前は一番最初の子だから、特別に上の線はなくていいよ」と、CSSが優しく声をかけてあげるようなイメージです。これで、美しく自然なメニューリストが完成します。
—
3. `:last-child`(最後の子)の出番:マージンの「あるある地獄」を救う
続いては、今回のもう一つの主役 `:last-child` です。こちらは、もちろん「兄弟の中で、一番最後に生まれた子」を選びます。
現場で一番多い使い道、それは「最後の要素の余白(マージン)をリセットする」という技です。
例えば、ニュース記事の一覧などを作っていて、いくつかのブロックが縦に並んでいるとします。
.news-item {
margin-bottom: 30px; / 次のブロックとの間に、ゆったりした隙間を作る /
}この書き方、一見すると綺麗に余白が空いて良さそうなのですが……ちょっと待ってください。
最後のブロックの下にも、ご丁寧に `margin-bottom: 30px` がついてしまっていませんか?そのせいで、親要素(コンテナ)との間に、意図しない無駄な隙間がぽっかり空いてしまう。これ、コーダーズ・ハイになりかけた人が夜中に頭を抱える「あるある」の瞬間です。
ここで `:last-child` の出番です!
/ リストやブロックの「最後の子」だけ、下の余白をゼロにする /
.news-item:last-child {
margin-bottom: 0;
}「今までみんなと同じように頑張ってきたけど、最後のお前だけは、最後の余白をゼロにしてすっきりと終わろうね」
そんな風に `:last-child` を設定してあげると、親要素のボックスの底面がピタッと綺麗に揃い、デザインの完成度がグッと跳ね上がります。プロっぽいたたずまいになりますよ。—
4. 教科書には載っていない? 現場でつまずきがちな「落とし穴」
さて、ここまで聞くと「なんだ、簡単じゃないか!」と思われるかもしれません。実際、概念はシンプルです。
しかし、CSSの沼はここからが本番(笑)。初心者の人がよくハマる、愛すべき「落とし穴」をこっそりシェアしておきますね。落とし穴:「あれ?一番最初を指定したのに、効かない……?」
例えば、以下のようなHTMLがあったとします。
お知らせ
今日のニュースです。
明日のニュースです。
ここで、「最初の `
` タグにだけ文字の色をつけたい!」と思って、こう書いたとします。
/ 「おっ、pタグの中の最初の子だから効くはず!」 /
p:first-child {
color: red;
}……あれ? 赤くなりません。なぜでしょうか?
答え:
`:first-child` が見ているのは、「親要素(今回の場合は `div.container`)から見て、一番最初にある要素」だからです。
`div.container` の中で、一番最初に生まれたのは `` タグではなく、お兄さんである `
` タグですよね。 つまり、`p:first-child` が探しているのは「親にとっての長男」なので、次男以降である ` ` タグには反応してくれないのです。 どう解決する?
もし「同じ種類の要素の中で最初・最後」を指定したい場合は、また別の優しい擬似クラス(`:first-of-type` など)が存在するのですが、それはまた別の機会に。
まずは、「`:first-child` や `:last-child` は、『親から見た、文字通り一番最初と最後の子』を見ているんだな」という大原則を、ぜひ頭の片隅に置いておいてくださいね。—
5. すぐに試せる!実践サンプルコード
それでは最後に、実際にエディタにコピペして、ブラウザでその動きを確かめられるサンプルコードをご用意しました。
デスクトップの片隅にメモ帳やVS Codeを開いて、試してみてください。
:first-child と :last-child の実験場
- ここに最初のカードが入ります(:first-child)
- ここに真ん中のカードが入ります
- ここに最後のカードが入ります(:last-child)
コードを眺めてみると、「最初の子」と「最後の子」にだけ、ちょっとした特別待遇(背景色の変更や、余白・ボーダーの打ち消し)が施されているのがお分かりいただけると思います。
—
おわりに
`:first-child` と `:last-child` は、派手なアニメーションを起こしたりするわけではありません。
しかし、こうした「細かいかゆいところに手が届くコード」をスマートに書けるかどうかが、プロの仕上がりと、素人っぽさが残る仕上がりの大きな分かれ道になります。最初は思い通りにいかなくてイライラすることもあるかもしれませんが、CSSはあなたが書いた指示を裏切りません。一つひとつ、仕組みを紐解いていけば必ず仲良くなれますよ。
今日の学びが、あなたの毎日のコーディングを少しでも楽しく、軽やかにするスパイスになれば、シニアアーキテクトとしてこれ以上嬉しいことはありません。
それでは、また次回の現場の知見でお会いしましょう!

コメント