全ての要素の最初や最後の子要素を指定する方法【CSS】

この記事の前提条件

対象: CSS(全モダンブラウザ対応)
難易度: ★☆☆
所要時間: 約5分

記事本文のような投稿ページでは、見出しや画像に上下の余白を付けておくのが基本ですが、そうすると一番上・一番下の要素にも余分な余白ができてしまいます。「最初の要素だけ余白を消したい」と調べると、大抵li:first-childのようなliタグ限定の書き方ばかりヒットしますが、投稿本文はh2やpなどタグの種類がバラバラなので、これでは対応できません。

タグの種類を問わず最初の要素を指定する: *:first-child

やりたいことは「pが来てもh2が来ても画像が来ても、とにかく一番最初の要素を指定したい」ということです。これは全称セレクタ(*)と組み合わせるだけで解決します。

.entry-content > *:first-child {
  margin-top: 0;
}

「親要素の中で一番最初の要素」という指定になるため、タグの種類を問わず、一番上の余白だけを0にできます。first-childlast-childに変えれば、同じ考え方で一番最後の要素を指定できます。

first-childとfirst-of-typeの違いに注意

first-childと似た名前のfirst-of-typeは、意味が異なるので混同に注意が必要です。

  • first-child: 兄弟要素の中で、タグの種類を問わず一番最初に来た要素にマッチ
  • first-of-type: 同じタグの中で一番最初に来た要素にマッチ(1番目の要素とは限らない)
⚠️ p:first-childが効かない、というつまずきパターン

「一番最初のp要素だけ余白を消したい」と思ってp:first-childと書いたのに反映されない——このパターンは、その要素の直前にp以外のタグ(h2など)があるケースでよく起こります。p:first-childは「兄弟の中で一番最初、かつタグがp」という意味なので、直前にh2があると条件を満たせません。同じタグの中での「最初のp」を指定したいだけなら、p:first-of-typeを使うのが正解です。

特定のクラスの中だけに絞り込む

ページ全体ではなく、特定のクラス(投稿本文のエリアなど)の中だけに適用したい場合は、対象のクラスを先頭に付け足すだけです。

.box *:first-child {
  margin-top: 0;
}

まとめ

  • *:first-childを使えば、タグの種類を問わず「一番最初の要素」を指定できる
  • 「最後の要素」を指定したい場合はlast-childに置き換える
  • first-child(兄弟内で最初)とfirst-of-type(同じタグの中で最初)は意味が違うため、狙い通りに効かない時はこの違いを疑う
  • 特定のクラスの中だけに絞りたい場合は、クラス名を前に付け足すだけでよい

投稿本文のように、どんなタグが最初に来るか分からないコンテンツの余白調整で特に重宝する書き方です。