4.6 结构关系选择器
术语说明。“结构关系选择器”对应w3c术语“complex selector复杂选择器”,对应MDN翻译“关系选择器”。本教程避开“复杂选择器”这一术语,日常表达“复杂的选择器”时使用“嵌套”相关表达,例如“嵌套选择器”或“复杂嵌套选择器”。结构关系选择器通常也称为关系选择器。
结构关系选择器主要包括4种:子元素选择器、后代选择器、相邻兄弟选择器、兄弟选择器。
4.6.1 为什么需要结构关系选择器
请先回顾“3.1.2 元素级别关系”。
一个页面可能包含几百个元素,就像一个学校有几百名同学。选择元素(同学)的逻辑比较复杂,使用简单选择器与复合选择器无法表达,例如“九班的男同学”。先通过选择器A找到“九班”,再通过选择器B找性别为男的同学,两个选择器需要组合;组合关系是“内部”,“内部”的逻辑即两个元素的结构关系是父子关系(或祖先-后代)。类似“内部”这种涉及到多个选择器之间的元素结构层级关系,需要使用结构关系选择器。
示例代码。下列选择器讲解以此代码为基础完成需求。
<body>
<div class="div1">
<p class="class1">第1段 小步教程 xiaobuteach.com class1</p>
<p class="class2">第2段 class2</p>
<p>第3段</p>
<div class="div2">
<p class="class1">第11段 class1</p>
<p>第12段</p>
<p class="class2">第13段 class2</p>
<p>第14段</p>
</div>
</div>
</body>
div1的子元素:第1~3段、div2。div2的子元素:第11~14段。
4.6.2 基本语法
结构关系选择器是复合选择器compound selector的一种组合:多个复合选择器通过结构关系符隔开,表示选择元素需要满足相应元素结构层级关系。
A 结构关系符 B
A、B、C等表示是复合选择器的任何一种形式,当然也包括简单选择器。结构关系符包括:空格、大于号、加号、波浪号。
4.6.3 子元素选择器
子元素选择器定义
A>B{/*样式定义*/}
两个选择器之间用大于号分开。当一个元素匹配选择器B,且父元素匹配选择器A,则此元素匹配此选择器。大于号前后加空格不影响含义。
需求场景:为类div1的儿子p元素增加相同样式。选择结果:第1~3段;div1的孙子p即第11~14段不要选择。
分析:父元素使用类选择器.div1,子元素使用标签选择器p,最终选择器代码如下。
.div1 > p{
border: 1px solid #999;
color: #0aaa76;
}
试一试。将A、B换成其它简单选择器。
4.6.4 后代选择器
后代选择器定义
A B{/*样式定义*/}
选择器之间用空格分开,此处的空格不能删除。当一个元素匹配选择器B,且任何一个祖先元素匹配选择器A,则此元素匹配此选择器。
需求场景:为div1的儿子p元素、孙子p元素等所有后代p元素增加相同样式。选择结果:第1~3,11~14段。
分析:祖先元素符合类选择器.div1,后代元素符合标签选择器p,代码如下。
.div1 p{
border: 1px solid #999;
color: #0aaa76;
}
试一试。将A、B换成其它简单选择器。
4.6.5 相邻兄弟选择器
相邻兄弟。比如四个兄弟,它们四个的关系都是“兄弟”,老大与老二、老二与老三、老三与老四,这种关系称为相邻兄弟,老大与老三不是相邻兄弟。相邻兄弟选择器定义如下。
A+B{/*样式定义*/}
选择器用加号隔开。A、B为相邻兄弟元素。加号前后有无空格不影响含义。
需求场景:选择class2,并且它的“相邻兄”是class1,也就是它平级的前面元素是class1。选择结果:第2段。
.class1 + .class2{
border: 1px solid #999;
color: #0aaa76;
}
4.6.6 兄弟选择器
兄弟选择器定义
A~B{/*样式定义*/}
选择器之间用波浪号隔开。A、B为兄弟元素。波浪号前后加空格不影响含义。
需求场景:选择class2,并且它的“兄弟”是class1,即只要平级元素是class1,无论前后。选择结果:第2、13段。
.class1 ~ .class2{
border: 1px solid #999;
color: #0aaa76;
}
4.6.7 结构关系嵌套
结构关系选择器能够进一步嵌套。例如:A与B组合成X,C与D组合成Y,X与Y进一步组合得到结构关系选择器Z。
形式示例
A B > C
A B > C + D
需求场景示例。(1)首先找标签是div且类名是div1的元素,(2)找上一步元素的后代元素的类名是div2的元素,(3)找上一步元素的子元素是标签p且类名是class1的元素,(4)找上一步元素的兄弟元素里类名是class2的元素。
div.div1 .div2 > p.class1 ~ .class2 {
border: 1px solid #999;
color: #0aaa76;
}
最终结果选中“第13段”。