CSS:nth-child和nth-of-type的深入理解
这两个选择器,可不是看起来那么简单的使用,如果没有彻底理解,蒙圈那是必须的——-如下代码:
第一个h1标题
第一个p。
第一个p.p。
第一个p段落。
第一个p.p段落。
第二个h1.p标题
第二个p。
第二个p.p。
第二个p段落。
第二个p.p段落。
结果:
image
看起来明明就是第一个啊,为啥就没反应??崩溃中... 别急,仔细分析分析吧,大有文章的。
:nth-child(n)
先来看看nth-child
官方解释是::nth-child(n) 选择器匹配属于其父元素的第 n 个子元素,不论元素的类型。
这个还是很好理解的:我就从当前父元素下开始数数,至于你是谁,我不认识,数到第n个元素,然后拿出来,好了,再看看你是不是和我找的匹配,是,那我就给你画一画,不是,那就啥也不做,拜拜吧。
看几个直观的栗子就了然了(声明:为了减少重复,所有的html结构都是开篇中代码的,后面就不在重复粘贴了):
1. 找第一个p,然而这样是找不到的,第一个元素不是p,是h1
p p:nth-child(1){
background: #ffff00;
}
结果:
所以要这样找,第2个元素才是p
p p:nth-child(2){
background: #ffff00;
}
结果:
2.按class类型找,结果一样,找.p元素,发现第一个 .p元素居然是第5个,同样第二个其实是第6个h1标签(可自行验证):
/*p .p:nth-child(1){
background: #ffff00;
} 无效的,第一个元素是h1,不是.p */
p .p:nth-child(5){
background: #ffff00;
}
结果:
3.如果没有指定的选择元素,则直接选择第n个元素:
p :nth-child(1){
background: #ffff00;
}
结果:
好了,换下一话题
:nth-of-type(n)
再来看看nth-of-type
官方解释::nth-of-type(n)选择器匹配属于父元素的特定类型的第 n 个子元素的每个元素。
嗯,就是当前父元素下,按元素类型(注意是元素类型,与class无关,理解这点很重要)分类后 ,在每一类元素中寻找属于该类元素的第n个值,然后匹配,成则成,否则罢。
嗯就是多了这么一层先分类,再在每一类中找,这就是很大的区别了,而且在按class类型选择的时候,有可能就绕进去了(就如开篇中那个崩溃的栗子)。
因为按元素名称选其实很好理解,分类完第几个就是第几个。这里就详细解释带class类型的选择,我们还是先看栗子(说明一下,按照定义,我们的栗子中父元素下有三类子元素,h1,p和p)
1.选择p中第一个包含.p的元素:
p p.p:nth-of-type(2) {
background: #ff0000;
}
结果
这里必须是2才能找到,写1的时候是找不到的(开篇的栗子),因为分类后,第二p元素才是有class类的,第一个是没有的。同理,找第二个包含.p的p元素,得写4,因为本例子中,一共四个p,其中第四个p才是第二次包含class类的。另外,注意这里强调了选择器复合选择器 p.p,这很重要,因为这样取出来的是一个值,下一个栗子是直接选类的,就会有多个值。
2.选择含有.p class的元素
p .p:nth-of-type(2) {
background: #ff0000;
}
/*有人会说如下这么选,也只选出了一个元素,那是因为在本例子中,符合条件的确实只有一个
p .p:nth-of-type(2) {
background: #ff0000;
}*/
结果:
看,选出两个,还是不同元素的,这首先说明,直接写class类选择不加复合限定,是找出每个元素类别中对应的第n个元素,然后匹配class,会有多个值,本例中,p和h1元素中的第二个元素刚好都符合,所以被选中。有的同学可能迷糊了,认为这个应该选出的是“第二个p.p段落”或者只有“第二个h1.p标题”这两种情况,这是因为没有理解“nth-of-type中先按父元素包含的元素分类(不是按你写的class分类,class只是用于最后匹配的)后,在分别寻找其中第n个,然后匹配”的规则。这句话要细细的理解:不是你所认为的第n个具有class的元素,而是每类元素中的第n个元素是否有这个class。
有的同学可能又会说了,不是啊,我平时这么写,选的就是按顺序来的,第二个有class的元素我也选中了呀,那是因为你写的代码凑巧都是同一类型的元素,并且所有元素都具有同样的class,这也是平时我们没有觉得这个选择器有怪异的原因。大家可以自行测试,写同一类元素,但是每隔一个,写一个class,你就会发现不一样了。就本例子,也可以说明,同类型的p元素,如果要选择第二个具有.pclass的元素,我得写.p:nth-of-type(4),这里的n实际是4而不是2。
这个地方多说了这么多,这也就是这个选择器会蒙圈的地方,我曾经就被坑了很久,希望看完以后希望能对这个选择器有重新的认识。
3.不指定元素的情况:
p :nth-of-type(2) {
background: #ff0000;
}
结果:
选中了每一类元素的第二个元素,理解了上一个栗子,这个就非常好理解了。
总结一下
啰嗦完了,要总结一下:
1.两选择器都是选择子元素的,都是从当前父元素开始查找;
2.nth-child系列包括first-child,last-child等等,都是只选择第n个元素,不管类型,然后匹配,所以无论如何,最多只有一项;
3.nth-of-type是将元素分类,然后选择每一类中的第n个,然后匹配,所以如果没有复合限定,可能会有多个匹配项;
4.谨记,nth-of-type在选择时,n值与父元素下当前类型元素中的顺序有关,与class次序无关,class只在最后匹配中有用。
上一篇: 关于访问控制的一首PHP面试题(对属性或方法的访问控制)
下一篇: css清除浮动的原因和方法