要想知道nth-child(n)到底作用到了哪些标签上,我们就不得不从选择器开始说起。
选择器
当我们使用了选择器,到底选中的是什么?
结论:不论选择器多复杂,最终选择到的都是标签
举一个例子:html的代码如下:
首先来看个简单的CSS代码:
body {}
十分明显,我们这里选择的是body标签。如果再加一点:
body ul{}
显而易见,我们这里选择的是body里所有的ul。也就是说目前所选中的标签只有2个:第14行的ul和第23行的ul,(注意:很多时候其子标签虽然会有CSS施加的效果,但那是得益于其父类,其自身并不是被选择器选中的标签)那如果是下面这样:
body ul p{}
我们选中的,就是第16,17,18和第25行的p标签。如果再多加一点,变成:
body ul p + p {}
那么我们可以一层层的看,首先先看前3个(body ul p)所确定的标签——也就是我们上面所提到的第16,17,18 和 25 行的 4 个 p标签,然后再分别去找这 4 个p标签的相邻兄弟,并检查此兄弟是不是p标签。
这样我们就可以得到:上面代码选中的标签是:第17和18行的p标签。
上面这个例子想强调的一点就是:即使我们写了body {background-color: pink;},整个网页背景都会变色,但被这个选择器被选中的,也仅仅只有body这一个标签而已。
明确了选择器究竟选择了谁这个概念后,我们再来看: nth-child(n)伪类
:nth-child(n)伪类
那么这个伪类到底是作用到谁(或者说选择到了谁)呢?
结论:该伪类选择的是:选择器所选中的标签
的父类的第n个孩子
。当然,和相邻兄弟选择器一样,在选中孩子后,还要去看此孩子是不是相应的类型,如果不是,就当没选中。
选择器:nth-child(n)
把上面2点相结合,我相信就可以很清楚得认识到,该伪类到底选择了谁。比如:
div:nth-child(1) {
background-color: palegoldenrod;
}
我们就可以这样分析:先看选择器到底选择了谁——因为body中只有一个div,所以该选择器就是选择了第13行的这个div标签。然后我们再来挨个分析伪类,我们前面说过——伪类选择的是:选择器所选中的标签
的父类的第n个孩子
。所以,这里选中的就是div
的父类(body)的第一个孩子(也就是div自身)
,所以相当于对div标签设置了背景颜色。再比如:
div ul p:nth-child(2){
background-color: palegoldenrod;
}
我们还是先看选择器——div ul p选择了什么。分析可得,该选择器选择了第16,17,18 和 25 行的p标签。然后再依次对这4个标签进行伪类分析:
第16行的p的父亲的第2个孩子是第17行的p,并且元素匹配,所以17行的p是被选中的标签。
第17行的p的父亲的第2个孩子也是第17行的p。
第18行的p的父亲的第2个孩子也是第17行的p。
第25行的p的父亲的第2个孩子为空。
所以,最终被选中的标签只有第17行的p,也就是说只有17行的p被设置了背景颜色。
元素匹配
相信通过这种分析,即使选择器很复杂,也能慢慢得找出被选择的标签是那个或哪些。不过关于元素匹配上,要注意id选择器和类选择器的一些细节,比如如果对上面代码中的div设置一个id:div0,再给此div增加一个div兄弟
那么
#div0 + div:nth-child(1) {
background-color: palegoldenrod;
}
是不会有任何元素被选中的,因为此选择器只选中了第二个,所以第一个div不会被认为是相匹配的元素。而
#div0 + div:nth-child(2) {
background-color: palegoldenrod;
}
自然就可以成功得第二个div变色。
也就是说,通过伪类找到的元素,必须也是被选择器选中的标签才行呢。
关于空格
无意中发现这样一件事:
#div0:nth-child(1) {}
和
#div0 :nth-child(1) {}
,如果大家运行一下,会发现有完全不同的效果
原因就在于第2个选择器:#div0空格
其实就代表了#div0下所有的后代标签,也就是说,不加空格时,就是选择了#div0这个标签,而加空格后,#div0的所有后代都被选中。然后我们再按上面说的方法分析,就可以知道那么标签为什么变色或不变色了。