CSS后代选择器探究

问题描述

在练习css时遇到后代选择器无法按理想情况选中的情况,故进行探索并记录。

若网页结构如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<body>
<ul>
<ol>
<li>List item 1-1</li>
<li>List item 1-2</li>
<li>List item 1-3</li>
</ol>
<ol>
<li>List item 1-1</li>
<li>List item 1-2</li>
<li>List item 1-3</li>
</ol>
</ul>
<ul>
<ol>
<li>List item 1-1</li>
<li>List item 1-2</li> //为该元素设置样式
<li>List item 1-3</li>
</ol>
<ol>
<li>List item 1-1</li>
<li>List item 1-2</li>
<li>List item 1-3</li>
</ol>
<ol>
</ul>

现在有需求:为第二个ul中的第一个ol中的第二个li设置color:red的样式,该如何选出?

错误操作尝试

错误操作:

1
ul ol li:nth-child(8){color;red}

该想法看起来很简单,似乎就是从ul开始,把里面各层级的所有的li全都选出来拿到一起,之后发现需要设置的的是第8个,用nth直接选出进行设置就好。但运行之后并不会有效果。

如果按照同样的思路,想把所有li中的第二个li单独设置,代码就会改为ul ol li:nth-child(2){color;red},运行后效果如下图,把每个ol中的第二个li都进行了设置。并不是想要的效果!

错误原因总结

经尝试,原因如下:

后代选择器深入到li层级后,在该层级搜索li,但因为所有的li并不是连续的,而是有相应的父级元素嵌套,所以li这一层级存在于四处地方,因此选择器会将选出的li分为四组,之后的nth操作本质上是对每一组进行操作。因此nt(2)其实是对每一组选出了第二个li

选择器的实际工作步骤为:

①先在body中遍历ul,发现存在两个且连续,因此成组;

②因为没有舍弃操作,因此对每个ul内部进行ol遍历,发现均存在两个连续的ol,因此分别成组,此时选择器就有了两个操作对象,内部都是找到的连续的ol;

③因为仍然没有舍弃操作,因此对每个组内的ol内部进行li的遍历,发现均存在三个连续的li,因此继续分别成组,此时选择器就有了四个操作对象,内部都是找到的连续的li

④之后在每组中,通过nth(8)去寻找操作对象,发现每组只有4个元素,因此找不到操作对象,操作失败。

示意图如下:

正确操作

1
ul:nth-child(2) ol:nth-child(2) li:nth-child(2) {color:red; font-weight:bold;}

其步骤原理在于:

①先在body中遍历ul,发现存在两个且连续,因此成组;

②通过nth(2)选出组内第二个ul,此时就已经舍弃了第一个ul;

③在第二个ul中遍历ol,发现存在两个且连续,将其成组;

④通过nth(2)选出组内第二个ol,此时舍弃了第一个ol;

⑤在第二个ol中遍历li,发现存在三个且连续,将其成组;

⑥通过nth(2)选出组内第二个ol,之后更改其样式

其选择流程示意图如下