ウェブサイト制作をしていると、繰り返し登場する任意の要素にスタイルを適用したい場面が多々あります。特に、リストやテーブルの特定の項目に異なるデザインを施す際に便利なのがCSSの疑似クラスです。この記事では、:first-child
、:last-child
、:nth-child
の疑似クラスを活用し、特定の要素にスタイルを適用する方法を学びます。
疑似クラスとは
疑似クラスは、CSSでHTML要素に追加のクラスを付けなくても特定の条件に基づいてスタイルを適用するためのものです。これにより、HTMLを変更せずにスタイル制御が可能になります。例えば、リスト項目の最初や最後の要素に特別なスタイルを適用することができます。
疑似クラスを使うとコードが簡潔になり、HTMLとCSSの分離が保たれるため、メンテナンス性が向上します。
:first-child疑似クラス
:first-child
疑似クラスは、親要素の中で最初の子要素を選択するための擬似クラスです。
.container :first-child {
...
}
このように書くことで、container
クラスの子要素のうち、最初の子要素を選択することができます。
:last-child疑似クラス
:last-child
疑似クラスは、親要素の中で最後の子要素を選択するための擬似クラスです。
.container :last-child {
...
}
このように書くことで、container
クラスの子要素のうち、最後の子要素を選択することができます。
:nth-child疑似クラス
:nth-child
疑似クラスは、親要素の中でn
番目の子要素を選択するための擬似クラスです。n
の部分には、数字やキーワード、または数式が入ります。
.container :nth-child(2) {
...
}
このように書くことで、container
クラスの子要素のうち、2番目の子要素を選択することができます。
:nth-last-child疑似クラス
:nth-child
疑似クラスは、:nth-child
の逆順で選択するための疑似クラスです。
.container :nth-last-child(2) {
...
}
このように書くことで、container
クラスの子要素のうち、最後から2番目の子要素を選択することができます。
:not疑似クラス
:first-child
疑似クラス、:last-child
疑似クラス、:nth-child
疑似クラス、:nth-last-child
疑似クラスの選択を否定したい場合、:not
疑似クラスを使用します。
.container :not(:first-child) {
...
}
このように書くことで、container
クラスの子要素のうち、最初の要素以外を選択することができます。
要素の適用に対する注意点
疑似クラスの適用範囲について、気をつけておいた方がよい点が2つあります。
親要素と子要素の関係性
例えば、次のようなHTMLを考えてみます。
<div class="container">
<div class="item">1-1</item>
<div class="item">1-2</item>
<div class="item">1-3</item>
</div>
<div class="container">
<div class="item">2-1</item>
<div class="item">2-2</item>
<div class="item">2-3</item>
</div>
<div class="container">
<div class="item">3-1</item>
<div class="item">3-2</item>
<div class="item">3-3</item>
</div>
このHTMLに対して、
.item:nth-child(odd) {
color: red;
}
を適用すると、どの文字が赤字になるでしょうか?
実際にやってみると一目瞭然ですが、
のように親要素.containerごとに子要素.itemの奇数番目の要素が赤字になることを確認することができます。同じ子要素の指定だとしても親要素を超えて処理されないという点に注意が必要なため、誤解や誤認を避けるために
.item:nth-child(odd) {
color: red;
}
のように子要素だけ定義するのではなく、
.container .item:nth-child(odd) {
color: red;
}
のように、親要素 子要素:疑似クラス
のように必ず親要素をつけて定義する方がよいと思います。
以降の説明でも、親要素をつけて定義する形式でスタイルを定義するようにしています。
複数種類の子要素が混在している場合
テーブルのように単一の子要素のみで構成される場合は問題ありませんが、複数種類の子要素が混在している状況では期待したとおりにスタイルが適用されない場合があります。
例えば、次のようなHTMLを考えてみます。
<div class="container">
<h2>タイトル</h2>
<p class="phrase">1行目</p>
<p class="phrase">2行目</p>
<p class="phrase">3行目</p>
<p class="phrase">4行目</p>
<p class="phrase">5行目</p>
</div>
phase
クラスが定義されたp
要素以外にh2
要素があります。
このHTMLに対して次のスタイルを適用します。
.container .phrase:nth-child(2n) {
color: red;
}
このスタイルでは、phase
クラスが適用された要素の偶数行目の文字を赤字にします。
実際にやってみると、期待したとおりの結果になりませんでした。疑似クラスを使用したとき、その要素が何個目であるかは指定したクラス(今回はphrase
クラス)の中で何個目かではなく、親要素から見たときに何個目の要素かで決まります。
すなわち、タイトル
が1個目、1行目
が2個目、2行目
が3個目、・・・という風に数えられ、その中で指定したクラス(今回はphrase
クラス)にのみスタイルが適用されます。
このことを確認するために、:first-child
疑似クラスを適用してみて色が変わらないこと、:last-child
疑似クラスを適用してみて色が変わることを確認しましょう。
まずは、:first-child
疑似クラスを確認します。
.pattern .phrase:first-child {
color: red;
}
:first-child
疑似クラスで指しているのはタイトル
で、phase
クラスが適用されていないため、色は変わりませんでした。
次に、:last-child
疑似クラスを確認します。
.pattern .phrase:last-child {
color: red;
}
:last-child
疑似クラスで指しているのは4行目
で、phase
クラスが適用されているため、色は変わりました。
1つの親要素の中に複数種類の子要素が混在する場合、何個目かは要素の種類に関係なく親要素から見て何個目かで数える点に留意してください。
パターン別
今回はすべて、以下のHTMLに対して適用するパターンで説明します。
<!DOCTYPE html>
<html lang="en">
<body>
<div class="container">
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
<div class="item"></div>
</div>
</body>
</html>
スタイルが適用されている要素はアクアで色づけし、スタイルが適用されていない要素はグレーのままになるようにします。
最初の要素にのみ適用
最初の要素にのみ適用したい場合は、:first-child
疑似クラスを使用します。
.container .item:first-child {
background-color: aqua;
}
最後の要素にのみ適用
最後の要素にのみスタイルを適用したい場合は、:last-child
疑似クラスを使用します。
.container .item:last-child {
background-color: aqua;
}
最初と最後の要素に適用
:first-child
疑似クラスと:last-child
疑似クラスを組み合わせることで、最初と最後のようにスタイルを適用することができます。
.container .item:first-child,
.container .item:last-child {
background-color: aqua;
}
最初の要素以外に適用
最初の要素以外にスタイルを適用したい場合、:first-child
疑似クラスとそれを否定する:not
疑似クラスを組み合わせることで実現できます。
.container .item:not(:first-child) {
background-color: aqua;
}
最後の要素以外に適用
最後の要素以外にスタイルを適用したい場合は、:last-child
疑似クラスとそれを否定する:not
疑似クラスを組み合わせることで実現できます。
.container .item:not(:last-child) {
background-color: aqua;
}
最初と最後の要素以外に適用
最初と最後の要素以外にスタイルを適用したい場合、:first-child
疑似クラス、:last-child
疑似クラス、:not
疑似クラスを組み合わせて実現します。こちらは最初の要素以外 かつ 最後の要素以外というAND条件になりますので、OR条件の場合とは書き方が異なります。
.container .item:not(:first-child):not(:last-child) {
background-color: aqua;
}
偶数個目の要素に適用
テーブルの行をストライプにするときによく使われるのが偶数個目または奇数個目の要素にスタイルを適用する方法です。これには:nth-child
疑似クラスを使用します。この書き方には2つあるのでそれぞれ説明します。
まずはn
を使って書く方法です。n
を使って偶数をあらわすためには2n
と書きます。
.container .item:nth-child(2n) {
background-color: aqua;
}
もう少し簡単に書く方法があります。偶数をあらわすeven
を使います。
.container .item:nth-child(even) {
background-color: aqua;
}
奇数個目の要素に適用
奇数個目の要素に適用する方法も2つあります。
まずはn
を使って書く方法です。n
を使って奇数をあらわすには2n+1
と書きます。
.container .item:nth-child(2n+1) {
background-color: aqua;
}
偶数のときと同じように簡単に書く方法があります。奇数をあらわすodd
を使います。
.container .item:nth-child(odd) {
background-color: aqua;
}
特定の要素に適用
:nth-child
疑似クラスを使うことで特定の要素にスタイルを適用することができます。
一例として、3個目の要素にのみ適用する場合を考えてみます。:nth-child
疑似クラスに3
を指定します。
.container .item:nth-child(3) {
background-color: aqua;
}
ただし、:nth-child
疑似クラスは万能ではありません。書けないケースや書き方に工夫が必要なケースもあります。
以下のようなことは:nth-child
疑似クラスで実現可能です。
- 特定の順序の要素を選択
:nth-child(2)
は、親の中で2番目に位置する子要素を選択します
- 特定のパターンに基づく要素を選択
:nth-child(odd)
または:nth-child(2n+1)
は、奇数番目の要素を選択します:nth-child(even)
または:nth-child(2n)
は、偶数番目の要素を選択します:nth-child(3n)
は、3番目、6番目、9番目など、3の倍数の位置にある要素を選択します
- 複雑なパターンで要素を選択
:nth-child(3n+1)
は、1番目、4番目、7番目など、3つおきに要素を選択します:nth-child(-n+3)
は、最初の3つの要素(1番目、2番目、3番目)を選択します
- 他の疑似クラスとの組み合わせ
:nth-child(2):hover
のように、特定の順序にある要素がホバーされたときのスタイルを指定できます
- 特定のタグに対して使用
p:nth-child(3)
のように、特定のタグ(例えばp
要素)が兄弟要素の中で指定された順序に位置する場合にスタイルを適用できます
一方で以下のようなことは:nth-child
疑似クラスではで実現できません。
- 特定のクラスや属性を持つ要素を選択
- 前述の注意点でも挙げたとおり、
:nth-child
疑似クラスは要素の順序に基づいているため、クラス名や属性を無視します。例えば、p.special:nth-child(2)
のように、特定のクラスを持つ2番目の要素を選択することはできません
- 前述の注意点でも挙げたとおり、
- 逆順の選択
:nth-child
疑似クラスは要素の逆順での選択はできません。例えば、末尾から2番目の要素を選択することはできません。ただし、:nth-last-child
疑似クラスを使用することで実現可能です
- 特定の要素タイプに対してだけの選択
:nth-child
疑似クラスは指定された順序にあるすべての子要素を対象とするため、特定の要素タイプだけを選択することはできません。例えば、特定の順序にあるdiv
要素だけを選択することはできません。div:nth-child(2)
は、2番目の子要素がdiv
要素である場合にのみ適用されます
an+b
の形式であらわせない要素を選択:nth-child
疑似要素では、2
などの特定値での指定、even
またはodd
、an+b
の形式(a
とb
は省略可)のいずれかの方法でしか指定できません。そのため、可変個数の要素のちょうど真ん中の要素に対してスタイルを適用するということはできません
an+b
の形式であらわせない形式であっても工夫によって表現可能な場合があります。例えば、1番目と4番目の要素に対してスタイルを適用したい場合、
.container .item:nth-child(1,4) {
background-color: aqua;
}
とは書けませんが、
.container .item:nth-child(1),
.container .item:nth-child(4) {
background-color: aqua;
}
と書くことで実現できます。
まとめ
:first-child
疑似クラス、:last-child
疑似クラス、:nth-child
疑似クラス(または:nth-last-child
疑似クラス)および:not
疑似クラスを使用することで、一部制約はあるものの様々要素を指定することができるようになります。
テーブルをストライプ模様にする以外にも、最初と最後の要素以外にマージンを設けたり、最初の要素だけデザインを変えたりなど、工夫によって様々なことができるようになります。
指定方法には少し注意すべき点がありますが、活用することでデザインの幅はさらに広がることでしょう。