网站
引入
HTML 中的元素按照层级结构组织,元素之间有父子关系、后代关系、兄弟关系。
有时候我们需要根据这些关系选中元素,例如”选中容器内的所有段落”、“选中直接子元素”、“选中相邻的兄弟元素”。
CSS 组合器就是用来根据元素之间的关系选中元素的。
正文
定义
定义
CSS 组合器用于组合多个选择器,根据元素在 HTML 文档树中的父子关系、后代关系或兄弟关系选中元素。
组合器本身不是选择器,而是连接多个选择器的符号,用来表达选择器之间的关系。
CSS 组合器对照表
| 组合器名称 | 符号 | 语法 | 作用与匹配规则 |
|---|---|---|---|
| 后代组合器 | 空格 | A B | 选中元素 A 内部的所有 B 元素。无论 B 是 A 的直接子元素,还是孙子、曾孙元素,只要嵌套在 A 内部都会被选中。 |
| 子代组合器 | 大于号 > | A > B | 仅选中元素 A 的直接(第一级)子元素 B。不包括更深层级的后代元素。 |
| 相邻兄弟组合器 | 加号 + | A + B | 选中紧跟在元素 A 后面的第一个同级元素 B。两者必须拥有相同的父元素,且 B 必须直接挨着 A。 |
| 通用兄弟组合器 | 波浪号 ~ | A ~ B | 选中元素 A 后面的所有同级元素 B。两者必须拥有相同的父元素,但 B 不必紧挨着 A。 |
具体说明
后代组合器(空格)
选中元素内部的所有后代元素,无论嵌套多深。
.container p {
color: blue;
}这条规则会选中 .container 内部的所有 <p> 元素,包括直接子元素和更深层级的后代元素。
子代组合器(>)
只选中元素的直接子元素,不包括更深层级的后代。
.container > p {
color: red;
}这条规则只会选中 .container 的直接子 <p> 元素,嵌套在更深层级的 <p> 不会被选中。
相邻兄弟组合器(+)
选中紧跟在某个元素后面的第一个同级元素。
h2 + p {
font-size: 18px;
}这条规则会选中紧跟在 <h2> 后面的第一个 <p> 元素,如果 <h2> 后面不是 <p> 或者中间有其他元素,则不会匹配。
通用兄弟组合器(~)
选中某个元素后面的所有同级元素。
h2 ~ p {
color: gray;
}这条规则会选中 <h2> 后面的所有同级 <p> 元素,不要求紧挨着。
代码示例
为了更直观地理解,假设我们有以下 HTML 结构:
<div class="container">
<p>我是直接子代段落 1</p>
<div class="inner">
<p>我是后代段落 2 (嵌套在 inner 中)</p>
</div>
<p>我是直接子代段落 3</p>
<span>我是一个 span</span>
<p>我是同级段落 4</p>
</div>针对上面的 HTML,这四种组合器的效果如下:
1. 后代组合器 (空格)
/* 选中 .container 内的所有 p 元素(段落 1、2、3、4 都会变成红色) */
.container p {
color: red;
}2. 子代组合器 ( > )
/* 只选中 .container 的直接子代 p 元素(段落 1、3、4 会变成蓝色,段落 2 不会,因为它是 inner 的子代) */
.container > p {
color: blue;
}3. 相邻兄弟组合器 ( + )
/* 选中紧跟在 .inner 后面的同级 p 元素(只有段落 3 会变成绿色) */
.inner + p {
color: green;
}4. 通用兄弟组合器 ( ~ )
/* 选中 .inner 后面的所有同级 p 元素(段落 3 和段落 4 都会变成紫色,span 会被跳过) */
.inner ~ p {
color: purple;
}例子
文章段落首行缩进
/* 文章中标题后面的第一段不缩进 */
h2 + p {
text-indent: 0;
}
/* 其他段落首行缩进 */
p {
text-indent: 2em;
}列表项分隔线
/* 给所有列表项添加顶部边框 */
li {
border-top: 1px solid #e5e7eb;
}
/* 移除第一项的顶部边框 */
li:first-child {
border-top: none;
}
/* 或者使用相邻兄弟组合器 */
li + li {
border-top: 1px solid #e5e7eb;
}表单标签和输入框间距
/* 标签后面紧跟的输入框添加顶部间距 */
label + input {
margin-top: 8px;
}特点
- 后代组合器(空格)选中所有后代元素,无论嵌套多深
- 子代组合器(
>)只选中直接子元素,不包括更深层级 - 相邻兄弟组合器(
+)选中紧跟在后面的第一个同级元素 - 通用兄弟组合器(
~)选中后面的所有同级元素 - 组合器可以连续使用,例如
div > ul > li - 组合器可以和其他选择器组合,例如
.box > p.intro - 组合器帮助我们根据 HTML 结构选中元素,不需要添加额外的
class
注意事项
- 后代组合器(空格)可能选中很多元素,注意性能影响
- 相邻兄弟组合器(
+)要求两个元素紧挨着,中间不能有其他元素 - 通用兄弟组合器(
~)只能选中后面的元素,不能选中前面的 - 子代组合器(
>)和后代组合器(空格)很容易混淆,要注意区分 - 组合器对 HTML 结构敏感,如果结构改变,样式可能失效
- 过度使用组合器可能导致样式和 HTML 结构耦合过紧,不利于维护
理解
可以把组合器理解为”关系选择工具”。
它让 CSS 能够根据元素在 HTML 树中的位置关系选中元素,而不需要给每个元素都添加 class。
例如,“容器内的所有段落”用后代组合器,“容器的直接子段落”用子代组合器,“标题后面的第一段”用相邻兄弟组合器,“标题后面的所有段落”用通用兄弟组合器。
组合器的核心价值是让选择器更精确、代码更简洁,同时减少不必要的 class 使用,让 HTML 结构更清晰。
但也要注意,过度使用组合器会让样式和 HTML 结构耦合过紧,如果 HTML 结构改变,样式可能需要大量修改。
引出
理解了组合器之后,可以继续学习:
也可以学习 CSS 预处理器(例如 Sass、Less),它们提供了更强大的嵌套和组合能力。