【備忘録】「:nth-child()」がどちゃくそ便利なのになぜ使わない?

ウェブ

どうも、河白です。

皆さんは「:nth-child」というCSSの擬似クラスをご存知でしょうか?
どうなんだろ。知っている人の方が多いのか、(ぼくの体感通り)少ないのか…。

というのも、ぼくが働いている職場では「:nth-child()」を使っている人が皆無だし、そしてぼくがコーディングでそれを使うと「使い方分からんからやめてくれ」と言われる始末。

何回も使い方や便利さを説明しているのだが…。

てことで、布教する意味も込めて備忘録記事を書きます。

「:nth-child()」って何?どこが便利?

「:nth-child()」は、「hover」とか「action」とかと同じCSSの擬似クラス。

どういう機能かというと、「n番目の項目だけ、このCSSを適応させる」ということができるようになります。

listタグで使うことが多いですね。

例えば以下のような、よく見る偶数行だけ色がついているリストを作るとします。

  • リスト①
  • リスト②
  • リスト③
  • リスト④
  • リスト⑤

考えられるのが、ソースに直接CSSを組み込む方法と

<ul>
	<li>リスト①</li>
	<li style="background:#ccc;">リスト②</li>
	<li>リスト③</li>
	<li style="background:#ccc;">リスト④</li>
	<li>リスト⑤</li>
</ul>

偶数のlistタグにclass指定をしてCSSを読み込ませるかです。

<ul>
	<li>リスト①</li>
	<li class="even">リスト②</li>
	<li>リスト③</li>
	<li class="even">リスト④</li>
	<li>リスト⑤</li>
</ul>

<style>
.even {background:#ccc;}
</style>

例では5項目だけなのでアレですが、これが幾十項目とかになってくると大変です。
しかも、作ったはいいものの後々に項目を増やす・減らす事になった時、その分ズレるのでまた編集し直さなくてはなりません。

そこで「:nth-child()」の登場です。

「:nth-child()」を使うと、こんな感じになります。

<ul>
	<li>リスト①</li>
	<li>リスト②</li>
	<li>リスト③</li>
	<li>リスト④</li>
	<li>リスト⑤</li>
</ul>

<style>
ul li:nth-child(2n) {background:#ccc;}
</style>

「:nth-child()」の()の中に、「n番目」の数値を入れます。
ここが「(3)」だと、3番目にのみ背景色が適応されます。
今回は偶数行なので、「(2n)」になります。

奇数なら「(2n+1)」、3の倍数行なら「(3n)」…といった具合。
ちなみに、一番最後の行のみに適応させたい場合は、「:last-child {…」と記述します。

厳密に言うと、偶数行は「:nth-child(even) {…」、1行目は「:first-child {…」など専用の数値がありますが、普通に「:nth-child(2n) {…」や「:nth-child(1) {…」と書いたほうが記述が早いし、やっぱかーえよって時に若干編集しやすいです。

「:nth-child()」の応用

ぼくはこの「:nth-child()」をサムネイルを作る時にめちゃくちゃ使ってます。

例えば、以下のような上位2つは2列、3位以降は3列というサムネイルレイアウトを作る時、みなさんはどう作りますか?

真っ先に思いつくのが、divを使って頑張って並べる方法ではないでしょうか。

<div id="boxcon">
    <div class="box1"></div>
    <div class="box1 last-box"></div>
    <div class="box2"></div>
    <div class="box2"></div>
    <div class="box2 last-box"></div>
</div>

<style>
#boxcon {
	width:90%;
	margin:10px auto 0;

}
.box1, .box2 {
	float:left;/* ボックスを左詰めにする */
	background:#333;/* ボックスの背景色 */
	height:100px;/* ボックスの高さ */
	margin:0 5% 20px 0;/* ボックスの隙間 */
}

.box1 {
	width:47.5%;/* 2行ボックスの横幅 */
}
.box2 {
	width:30%;/* 3行ボックスの横幅 */
}

.last-box {
	/* 一番右ボックスの右側隙間の削除 */
	margin-right:0;
}
</style>

これを実際に表示させると、こんなカンジ。

うまく表示できました!

…でもちょっと待って下さい。
もし、このサムネイルに上位3項目を追加しようとすると、こうなってしまいます。

<div id="boxcon">
    <div class="box1"></div><!-- 追加分 -->
    <div class="box1"></div><!-- 追加分 -->
    <div class="box1"></div><!-- 追加分 -->
    
    <div class="box1"></div>
    <div class="box1 last-box"></div>
    <div class="box2"></div>
    <div class="box2"></div>
    <div class="box2 last-box"></div>
</div>

これをまたソース・CSS両方さわって調整して…って面倒くさいですよね。

これを「:nth-child()」を使うと…

<ul id="boxcon">
    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

<style>
#boxcon {
	width:90%;
	margin:10px auto 0;	
}
li {
	float:left;/* ボックスを左詰めにする */
	background:#333;/* ボックスの背景色 */
	width:30%;/* ボックスの横幅 */
	height:100px;/* ボックスの高さ */
	margin:0 5% 20px 0;/* ボックスの隙間 */
}

li:nth-child(-n+2) {
	/* 1つ目・2つ目のボックス横幅 */
	width:47.5%;
}

li:nth-child(2),
li:nth-child(3n+2) {
	/* 2つ目と3n+2番目のみ右側隙間の削除 */
	margin-right:0;
}
</style>

こうなります。

構造がスマートになったし、劇的にソースを簡略化することができました。

実際に表示してみても、全く差し支えありません。

また、上位3項目だろうが何項目追加しても…

<ul id="boxcon">
    <li></li><!-- 追加分 -->
    <li></li><!-- 追加分 -->
    <li></li><!-- 追加分 -->

    <li></li>
    <li></li>
    <li></li>
    <li></li>
    <li></li>
</ul>

1つ目と2つ目は2列で、それ以降は3列に配置してくれます。
後の追加・削除の編集がめちゃ楽になります。

ね、使いたくなってきたでしょ?

「:nth-child()」のセレクタ

:nth-child(数字)

(数字)番目のみ適応させます。

  • :nth-child(2):2番目のみ
  • :nth-child(10):10番目のみ

また、「n」を使うことで「nの倍数番目のみに適応させる」など式を使って指定することもできます。

  • :nth-child(n):すべての項目
  • :nth-child(2n):偶数行
  • :nth-child(2n+1):奇数行
  • :nth-child(n+5):5番目以降すべて
  • :nth-child(-n+5):1~5番目のみ

:nth-child(even)

偶数項目のみ適応させます。

「:nth-child(2n)」と同じ。

:nth-child(odd)

奇数項目のみ適応させます。

「:nth-child(2n+1)」と同じ。

:first-child

1番目のみ適応させます。

「:nth-child(1)」と同じ。

:last-child

一番最後の項目のみ適応させます。

:nth-last-child(数字)

最後から(数字)番目のみ適応させます。

  • :nth-last-child(2):最後から2番目のみ
  • :nth-last-child(10):最後から10番目のみ

また、「-n+(数字)」を使うこともできます。

  • :nth-last-child(-n+5):最後から1~5番目のみ

:not(:nth-child(数字))

(数字)番目以外の項目に適応させます。

  • :not(:nth-child(7)):7番目以外すべて

複合表記

「:nth-child()」はいくつかの条件を複合して表記することができます。

ただし!AND(~かつ~)指定になるので、純粋に複数項目を指定する場合はカンマで区切って指定しましょう。

作り方は簡単で、そのまま並べて書いてあげればいいだけです。

  • :not(:nth-child(4)):nth-child(2n):4番目以外かつ偶数行
  • ::nth-child(-n+10):nth-child(2n+1):1~10行まででかつ奇数行

listタグ以外にも使える!!

色々な要素のあるソースで使うとこうなってしまう

基本、listタグで使うことが多いですが、他タグでも使うことができます。

例えば、

<div>
	<p>項目①</p>
	<p>項目②</p>
	<p>項目③</p>
	<p>項目④</p>
	<p>項目⑤</p>
</div>

このようなソースがあった場合、兄弟関係にある要素…ここで言うpタグに「:nth-child()」を使うことができます。
※兄弟関係とは、指定した要素と同階層にある要素を指します。

ただ気をつけなければならないのが、兄弟関係にある要素間で何番目かを計算するので、

<div>
	<h2>見出し</h2>
	<p>項目②</p>
	<p>項目③</p>
	<p>項目④</p>
	<p>項目⑤</p>
</div>

このような場合はh2タグもカウントされてしまい、pタグの偶数行を指定したくて「p:nth-child(2n)」と書くとpタグの奇数行が選択されてしまう…という現象が起きます。

予めpタグ以外の要素を算出して逆算して…とやるのもいいですが、コレマタ後々編集する時に手間がかかるしスマートじゃありません。

そこでコイツを使います。

「:nth-of-type()」という擬似クラス

「:nth-of-type()」を使うと、指定したタグかつ兄弟関係の要素内でカウントしてくれます。

つまり、「p:nth-of-type(2n)」と書くと、h2タグはカウントから除外され、きちんとpタグの偶数行が指定されます。

複数種の要素がある中で指定した時、なんかズレるなぁ~~ってときは上記が原因かもしれません。
そんな時は、「:nth-of-type()」を頼ってみましょう。

コメント

  1. […] 【備忘録】「:nth-child()」がどちゃくそ便利なのになぜ使わない?どうも、河白です。皆さんは「:nth-child」というCSSの擬似クラスをご存知でしょうか?どうなんだろ。知っている人の方が […]

タイトルとURLをコピーしました