CSS:nth-child和nth-of-type的深入理解

啰嗦一句

这两个选择器,可不是看起来那么简单的使用,如果没有彻底理解,蒙圈那是必须的——-如下代码:

<style>
div .div:nth-of-type(1) {
	background: #ff0000;
}
</style>
<body>
	<div>
		<h1>第一个h1标题</h1>
		<div>第一个div。</div>
		<div class="div">第一个div.div。</div>
		<p>第一个p段落。</p>
		<p class="p">第一个p.p段落。</p>
		<h1 class="p">第二个h1.p标题</h1>
		<div>第二个div。</div>
		<div class="div">第二个div.div。</div>
		<p>第二个p段落。</p>
		<p class="p">第二个p.p段落。</p>
	</div>
</body>

结果:

image

看起来明明就是第一个啊,为啥就没反应??崩溃中... 别急,仔细分析分析吧,大有文章的。

:nth-child(n)

先来看看nth-child

官方解释是::nth-child(n) 选择器匹配属于其父元素的第 N 个子元素,不论元素的类型。

这个还是很好理解的:我就从当前父元素下开始数数,至于你是谁,我不认识,数到第n个元素,然后拿出来,好了,再看看你是不是和我找的匹配,是,那我就给你画一画,不是,那就啥也不做,拜拜吧。

看几个直观的栗子就了然了(声明:为了减少重复,所有的html结构都是开篇中代码的,后面就不在重复粘贴了):

1. 找第一个div,然而这样是找不到的,第一个元素不是div,是h1


div div:nth-child(1){
    background: #FFFF00;
}

结果:

所以要这样找,第2个元素才是div

div div:nth-child(2){
	background: #FFFF00;
}

结果:

2. 按class类型找,结果一样,找.p元素,发现第一个 .p元素居然是第5个,同样第二个其实是第6个h1标签(可自行验证):

/*div .p:nth-child(1){
    background: #FFFF00;
} 无效的,第一个元素是h1,不是.p  */

div .p:nth-child(5){
    background: #FFFF00;
}

结果:

3. 如果没有指定的选择元素,则直接选择第n个元素:

div :nth-child(1){
	background: #FFFF00;
}

结果:

好了,换下一话题

:nth-of-type(n)

再来看看nth-of-type

官方解释::nth-of-type(n)选择器匹配属于父元素的特定类型的第 N 个子元素的每个元素。

嗯,就是当前父元素下,按元素类型(注意是元素类型,与class无关,理解这点很重要)分类后 ,在每一类元素中寻找属于该类元素的第n个值,然后匹配,成则成,否则罢。

嗯就是多了这么一层先分类,再在每一类中找,这就是很大的区别了,而且在按class类型选择的时候,有可能就绕进去了(就如开篇中那个崩溃的栗子)。

因为按元素名称选其实很好理解,分类完第几个就是第几个。这里就详细解释带class类型的选择,我们还是先看栗子(说明一下,按照定义,我们的栗子中父元素下有三类子元素,h1,div和p)

1. 选择div中第一个包含.div的元素:

div div.div:nth-of-type(2) {
	background: #ff0000;
}

结果

这里必须是2才能找到,写1的时候是找不到的(开篇的栗子),因为分类后,第二div元素才是有class类的,第一个是没有的。同理,找第二个包含.div的div元素,得写4,因为本例子中,一共四个div,其中第四个div才是第二次包含class类的。另外,注意这里强调了选择器复合选择器  div.div,这很重要,因为这样取出来的是一个值,下一个栗子是直接选类的,就会有多个值。

2. 选择含有.p  class的元素

div .p:nth-of-type(2) {
	background: #ff0000;
}

/*有人会说如下这么选,也只选出了一个元素,那是因为在本例子中,符合条件的确实只有一个
div .div: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元素,如果要选择第二个具有.p class的元素,我得写.p:nth-of-type(4),这里的n实际是4而不是2。

这个地方多说了这么多,这也就是这个选择器会蒙圈的地方,我曾经就被坑了很久,希望看完以后希望能对这个选择器有重新的认识。

3. 不指定元素的情况:

div :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只在最后匹配中有用。

更多内容和js插件,欢迎点此访问个人主页! 文章链接

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值