人人网FED博客

专注于前端技术

被多数人误解的nth-of-type

nth-of-typeCSS3的一个结构性伪类选择器,很多人都知道nth-of-type(n)用于匹配父元素下使用同种标签的第n项子元素,但是也有不少人对这个选择器存在着一些误解。先说一个在使用nth-of-type时可能碰到的问题:

1.为什么nth-of-type挂了?

在这里给出DOM结构如下:

如果我们希望改变class为.child的第1个段落元素的样式,可能会把css写成下面这样:

但是运行结果却是:
这里写图片描述
.child:nth-of-type(1)的样式没有作用到任何一个段落元素上。为什么这样定义的样式会不生效呢?让我们先看一下nth-of-type的定义。

2.nth-of-type的定义

nth-of-type里既然有个type,就表示它是按照元素类型来进行选择的,它的选择范围是父元素下某一种元素类型的集合。
ele:nth-of-type(n)表示选择父元素下的第n个ele元素,其中n可以是正整数、公式或者关键字。
n为正整数,如p:nth-of-type(2)表示选择父元素下的第2个p元素。
n为公式,如p:nth-of-type(2n+1)表示选择父元素下的每一个奇数项的p元素。
n为关键字,有even(偶数,等价于2n)和odd(奇数,等价于2n+1)两种。

举个例子,就拿下面的DOM结构来说,我们分别用nth-of-type给它定义不同的样式:

CSS代码:

运行结果:

这里写图片描述

 

这里写图片描述

 

这里写图片描述

由以上运行结果,几个选择器分别选择到了父元素下的第二个p元素、所有偶数项的p元素以及所有奇数项的p元素,这些结果都是没有问题的。可以说,标签名+nth-of-type是一种非常靠谱的使用模式,基本上不会遇到什么问题。那么,当使用class+nth-of-type时,情况就不一样了。

3.nth-of-type与class结合使用

1)同种类型元素拥有同一个class

这种就是本文一开始时候提到的情况,让我们回到上面的第一个例子:

运行结果:
这里写图片描述

根据以上nth-of-type的定义可知,nth-of-type这个选择器是根据元素的类型去选择的。
当解析到.child:nth-of-type(1)时,浏览器一开始并不知道要选择的元素类型是什么,它会先找到.child这个类名,找到.child之后得知p元素拥有这个class,所以此时浏览器就知道了它要从p元素里面去匹配,就变成了p.child:nth-of-type(1),找到了第一个p元素之后判断它有没有.child类名,有就匹配到该元素,没有则匹配不到任何元素。

所以,在这里要匹配到第1个拥有.child的p元素,应该将代码改成:

要匹配到第2个拥有.child的p元素,则把代码写成:

2)多种不同类型的元素拥有同一个class

重新修改DOM结构如下:

运行结果:
这里写图片描述

此时.child:nth-of-type(2)同时匹配到了第二个p元素和第二个span元素。浏览器会先去找.child这个class,找到.child后会把拥有.child这个类名的不同类型的标签分别划分到不同的组里面,再从这些组中分别进行选择。

总结下来就是:
.class:nth-of-type(n)会同时选择到所有具有.class的元素类型组中的第n个拥有.class类的元素。
也就是说.class:nth-of-type(n)相当于*.class:nth-of-type(n),它会匹配到所有拥有.class的*:nth-of-type(n),*在这里表示拥有.class的元素类型。
以上例子中的.child:nth-of-type(2)就相当于p.child:nth-of-type(2),span.child:nth-of-type(2)。也就是拥有.child的所有p:nth-of-type(2), span:nth-of-type(2)。

目录: 基础技术

Tags: ,

3 回复

  1. 这里有些问题吧,https://codepen.io/Toomo/pen/EvxxBJ那这个例子来说,ul>li{content}*3+li.item{content}*7来说,按道理li.item:nth-of-type(2n)的计数从第四个li开始计数,那么偶数位的选择到的应该是5,7,9,然而实际的表现却和li:nth-of-type(2n)一致,只是排除了非.child的元素。

    • 不是这样的,如果您认为li.item:nth-of-type(2n)的计数从第四个li开始计数,就恰恰陷入了类似文中第一个例子‘为什么nth-of-type定义没有生效’的误区中。实际上它是从第一个li开始的。
      因为nth-of-type是按照元素的类型去匹配,所以li.item:nth-of-type(2n)恰恰就是先匹配的li:nth-of-type(2n),然后再去判断有没有.item类名。也就是说这里面的2n匹配到的是li元素的偶数,而不是.item的偶数。
      li.item:nth-of-type(2n)先找到了2、4、6、8但是因为2不存在.item所以把2去掉了,最后的结果就剩下了4,6,8。

Trackbacks

  1. 【转】被多数人误解的nth-of-type – 大志设计

发表评论

电子邮件地址不会被公开。 必填项已用*标注