混乱しがちなこの二つのcssにここで決着をつけましょう。
<section>
<p>"親の一番目の子供かつ一番目のpタグ!"</p>
<p>"親のニ番目の子供かつニ番目のpタグ!"</p>
<p>"親の三番目の子供かつ三番目のpタグ!"</p>
</section>
p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }
-
element:nth-child(x)
は- 指定されたelementタグ、かつ
- 指定されたelementタグの親要素のx番目の子要素
を満たす要素をターゲットにする。
→つまり、上の例でいうと、(条件1)指定されたpタグかつ、(条件2)その親要素sectionないの2番目の子要素、のニ条件を満たす<p>"親のニ番目の子供かつニ番目のpタグ!"</p>
が選ばれる。
-
element:nth-of-type(x)
は- 指定されたelementタグの親要素の子供の中のそのタグ内順位がx番目の要素を選ぶ
→上の例でいうと、(条件1)指定されたpタグの親要素section内のpタグ内で2番目の要素である<p>"親のニ番目の子供かつニ番目のpタグ!"</p>
が選ばれる。
なんじゃい一緒かい!と思うかもしれないが、この違いが出てくるケースを理解することで本質的に違いを理解したい。
違いは以下のような例の時に出てくる。
<section>
<h1>"親の一番目の子供かつ一番目のh1タグ!"</h1>
<p> "親のニ番目の子供かつ一番目のpタグ!"</p>
<p> "親の三番目の子供かつニ番目のpタグ!"</p>
</section>
p:nth-child(2) { color: red; }
p:nth-of-type(2) { color: red; }
おわかりでしょうか。
- この場合、p:nth-child(2)
は(条件1)指定されたpタグかつ、(条件2)その親要素section内の2番目の子要素、のニ条件を満たす <p> "親のニ番目の子供かつ一番目のpタグ!"</p>
を選ぶのである。(直感的には、pの2番目の子!って言ったらp内で2番目が選ばれそうなんだけどね。ここが混乱するポイントかと。あくまで、そのタグの親要素をみて、親要素にとってタグ関係なしにx番目の子要素を選び出すのです。)
- 一方、
p:nth-of-type(2)
は(条件1)指定されたpタグの親要素section内のpタグ内で2番目の要素である<p> "親の三番目の子供かつニ番目のpタグ!"</p>
を選び出すのである。
違い分かったでしょうか。
もっと言ってしまえば、
<section>
<h1>"親の一番目の子供かつ一番目のh1タグ!"</h1>
<h2>"親のニ番目の子供かつ一番目のh2タグ!"</h2>
<p> "親の三番目の子供かつ一番目のpタグ!"</p>
<p> "親の四番目の子供かつニ番目のpタグ!"</p>
</section>
p:nth-child(2) { color: red; }
で何が選ばれると思います?
答えは、何も選ばれない、です。なぜならば上で挙げた二つの条件を満たす要素はここでは存在しないからですね。しかし、nth-type
を使えば、機能しますね。
結論としては、直感的に使いやすく破城しにくいのは、nth-type
の方なんじゃないでしょうか?
だって、「もし親の子要素の2番目がpタグだったらそのpタグを選びたい、そうでなければ何も選びたくない!」なんて思わないよね。めったに。むしろ「2番目のpタグ要素を選びたーい」だよね。よくあるのは。
注意点
-
classベースでやることはできない。
http://stackoverflow.com/questions/6447045/css3-selector-first-of-type-with-class-name -
first-of-typeは指定要素の親の最後のtypeに繋げるわけなので、type指定必須。
.hoge {
~~
&:first-of-type {
//これ無理。type指定してないので。
}
}
.hoge {
~~
div:first-of-type {
//こう書ける。div指定してる。
//これだとhoge以下のdiv全てを対象としていて、
//子要素のdivの最初対象かつ孫要素のdiv内での最初も対象で、そのまた子供の...ってなって多分好ましくない。
}
>div:first-of-type {
//こうやって子セレクタを指定して、
//直接の子供のdiv内での最初を対象ってするのが
//よく求められる動きでしょう。
}
}
- first-childは指定要素の親の最後の子要素に繋げるわけでtype指定は別にいらん。クラスでもなんでも要素さえ指定すればその親をみて、この最後を持ってくる。
.hoge {
~~
&:first-child {
//これおk。
//hogeクラスを持った奴の親要素の一番最初の子要素ターゲット。
}
}
関連
:first-of-type
:last-of-type
:nth-last-of-type
:only-of-type
たちも相当便利。
参考