CSS Handbook · 选择器

第二章 / 2.2 组合选择器与优先级

第二章 · 2.2 节

组合选择器与优先级


把基础选择器按不同的连接符组合起来,就能精确描述元素之间的结构关系。理解这四种组合方式,再加上一套优先级计算规则,就能预判任何一条 CSS 规则最终会不会生效。

后代选择器(空格)

两个选择器之间以空格分隔,匹配前者内部任意深度的后代元素,不要求直接嵌套。

.article p {
  color: #5c5872;
}

无论 p.article 的直接子元素,还是被包裹在多层 div 中,都会命中。

子代选择器(>

只匹配直接子元素,不会穿透更深的层级,常用于避免样式意外污染嵌套组件。

.nav > li {
  display: inline-block;
}
实践建议在编写组件库样式时,优先使用子代选择器而非后代选择器,能有效避免样式"渗透"进组件内部嵌套的同名标签。

相邻兄弟选择器(+

匹配紧跟在前一个元素之后、且拥有相同父元素的下一个兄弟节点。

h2 + p {
  margin-top: 0;
}
效果预览:紧邻标题的段落取消上边距
小标题
紧跟其后的段落,margin-top 被清零。

通用兄弟选择器(~

匹配同一父元素下、在前一个元素之后出现的所有符合条件的兄弟节点,不要求紧邻。

.tab-radio:checked ~ .tab-panel {
  display: block;
}

这也是"纯 CSS 标签页 / 手风琴"技巧的核心原理:借助 :checked 状态与通用兄弟选择器联动,无需 JavaScript。

优先级计算

当多条规则同时命中同一元素的同一属性时,浏览器按"优先级"高低决定生效的声明。优先级由四个等级构成,从高到低依次为:

等级示例权重记法
内联样式style="color:red"1,0,0,0
ID 选择器#nav0,1,0,0
类 / 属性 / 伪类.btn / [type] / :hover0,0,1,0
标签 / 伪元素div / ::before0,0,0,1

逐级比较,高位相同再比下一位;!important 会越过以上所有等级,应当谨慎使用。例如 .nav .item.active 的权重是 0,0,2,0,高于 .item0,0,1,0),但低于 #nav .active0,1,1,0)。

.item { color: gray; }         /* 0,0,1,0 */
.nav .item.active { color: teal; } /* 0,0,2,0 —— 生效 */

层叠与来源顺序

当两条规则优先级完全相同时,"层叠"(Cascade)规则介入:后声明的规则覆盖先声明的规则。这也是为什么 CSS 文件的书写顺序、以及 <link> 标签的引入顺序会影响最终效果。现代 CSS 还引入了 @layer 层叠层,可以显式控制不同来源样式之间的覆盖关系,这里先作了解,留待进阶主题展开。