组合选择器
组合器把 HTML 的树关系写进选择器。空格表示后代,> 表示直接子代,+ 表示相邻兄弟,~ 表示后续兄弟。它们不是排版命令,而是匹配条件;关系改变,匹配集合也会改变。
css
article p { color: #333; }
article > header { border-block-end: 1px solid; }
h2 + p { margin-block-start: 0; }
input:checked ~ .details { display: block; }article p 会命中嵌套很深的所有段落,article > header 只命中直接子代。过宽的后代选择器容易污染嵌套组件,过度依赖 DOM 层级又会让结构调整变成样式破坏。优先用稳定的组件边界和语义类名表达意图。
组合器与状态可以一起工作
最后一个例子把表单控件状态和兄弟关系连起来。选择器不会读取业务变量,也不会主动改变 DOM;它只根据当前树和元素状态重新匹配。交互复杂时,应判断 CSS 状态是否足够,还是需要脚本与明确的状态模型。
实验与练习
创建一个包含嵌套 article、标题、段落和复选框的页面。分别用后代、直接子代、相邻兄弟和后续兄弟选择器标记目标元素,在开发者工具中记录匹配集合。移动一个节点的位置后,解释哪些规则失效以及如何用稳定类名减少结构耦合。
可运行微实验:从匹配到胜出
在一个页面中保留三个同名元素,给它们同时设置类型、类、属性和伪类规则。先在 Elements 的 Matched CSS Rules 记录“命中但未胜出”的声明,再只改变一个条件:元素增加类、属性值改变、祖先增加类或规则移入另一层。每次只记录匹配集合、特异性/层级和最终 computed value,避免把“选择器没命中”和“命中了但被覆盖”混为一谈。
html
<p class="notice" data-state="error">消息</p>
<style>p { color: gray } .notice { color: navy } [data-state="error"] { color: crimson }</style>常见错误
- 把后代选择器当成组件作用域。
- 以为
>会匹配所有后代。 - 调整 HTML 缩进却没有改变结构,或反过来改变嵌套却只检查视觉结果。
- 用复杂关系选择器替代清晰的状态类或组件边界。
继续阅读
下一篇让选择器根据属性值和存在性命中元素:属性选择器。
练习
- 用最小输入复现“组合选择器”的成功路径,并记录可观察结果。
- 改变一个时序、数据或宿主条件,解释结果为何变化。
- 删除清理、校验或降级分支,写出能证明缺陷的断言。