まずはこちらのHTMLから・・・:
<section> <p>Little</p> <p>Piggy</p> <!-- Want this one --> </section>
p要素2番目のpタグにスタイル設定したかった場合、以下のどちらも同じ働きをしてくれます:
p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }
けれど勿論相違点もあります。
:nth-childセレクタをシンプルに説明すると:
パラグラフ要素である親要素に包有される2番目の子要素である。これらの状態を満たす要素を選択するということになります。
:nth-of-typeセレクタをシンプルに説明すると:
親要素に包有される2番目のパラグラフ子要素を選択するということになります。
よく言えば、:nth-of-typeの方が「条件が少なくて済む」という感じですね。
それではマークアップを以下の様に変更したとします:
<section> <h1>Words</h1> <p>Little</p> <p>Piggy</p> <!-- Want this one --> </section>
今度はこちらの記述ではうまくいきません:
p:nth-child(2) { color: red; } /* うまくいかない */
こちらはうまくいきます:
p:nth-of-type(2) { color: red; } /* うまく適用される */
初めの:nth-childセレクタの方が何故うまくいかないかと言うと、<h1>Words</h1>が追加されたことにより、パラグラフ要素(1)であり、しかも2番目の子要素(2)である条件が当てはまるのは、「Little」になってしまったからです。そのため:nth-childセレクタは「Piggy」ではなく「Little」を選択します。:nth-of-typeセレクタの方で問題がないのは、「Piggy」が親要素に含有される2番目のパラグラフ要素であることに変わりがないからです。
それではもし<h1>タグの後ろに<h2>タグを追加したとしたら、どうなるでしょう。今度は2番目の子要素はp要素ではなくh2要素になります。従って上記2つの条件に当てはまる要素は存在しなくなってしまうため、これまたうまくいきません。けれど:nth-of-typeセレクタの場合は、引き続き問題なく表示されます。
なんとなく今まで:nth-childの方が一般的だと思っていましたが、:nth-of-typeの方が便利で使い勝手がよさそうですね。「もし2番目の子要素がたまたまパラグラフ要素だったら、選択する。」なんて条件を使う気になりますか?そういうことも稀にあるかもしれませんが、それよりも:nth-of-typeを使って「2番目のパラグラフを選択する」とか「テーブル内の行を3行おきに選択する」とした方が、断然使い易いような気がします。
私が「ちょっと待ってよ。なんで:nth-childセレクタがうまくいかないんだ?」と思うときは大抵指定した子要素の番号がずれてしまっている時だったりします。そのため:nth-childを使用する時には、下記のサンプルの様に親要素に縛りをかけて、子要素自体は特定しないで置いておいた方が良いかと思います。
dl :nth-child(2) { } /* こちらの方がよい */ dd:nth-child(2) { }
勿論その時々の状況によりけりですけれどね。
各ブラウザのバージョンで言うとFirefox 3.5+、Opera 9.5+、Chrome 2+、Safari 3.1+、IE 9+で:nth-of-typeをサポートしています。jQueryを使えば更に深いサポートが可能になりますが、jQueryでは:nth-of-typeの方はサポートを止めてしまいました。なんだかおかしな話ですよね。最初に聞いたときは使用回数が少ないのが原因かと思いました。(ちなみにjQueryを使って記述する場合は、セレクタを使ってクラスを適用させ、そのクラスにスタイル設定します。\$("セレクタ").css("スタイル設定");)こちらのサイトでは、:nth-of-typeをサポートするプラグインをダウンロードすることが出来ます。
他にも関連セレクタとして「:first-of-type」「 :last-of-type」「 :nth-last-of-type」「 :only-of-type」などもありますので、お忘れなく!こちらで更に詳しく説明しています。
もし視覚的サンプルを試してみたければ、リア・ヴェローさんが作ったこのツールが面白いですよ。