在网页样式开发中,选择器决定了哪一部分DOM节点会应用某组规则。CSS3相较CSS2.1增加了大量实用选择器,使我们可以脱离繁琐的class命名,直接依据文档结构、元素属性以及交互状态来定位目标。理解这些选择器的匹配逻辑与优先级表现,是写出可维护样式表的基础。

基础选择器与组合关系
最常被使用的基础选择器包括类型选择器、类选择器、ID选择器、通配选择器以及属性选择器中的简单形式。类型选择器直接以元素名匹配,例如 div 会选中所有div元素;类选择器通过 .name 形式匹配class包含该值的节点;ID选择器以 #id 匹配唯一标识。它们的权重依次递增,ID优先级高于类,类高于类型。通配选择器 * 匹配任意元素,通常用于重置默认边距,但会带来一定性能开销,不宜在大文档中滥用。
组合选择器用于表达节点之间的位置关系。后代选择器 section p 选中section内所有层级的p;子选择器 ul > li 仅选中直接子级li;相邻兄弟选择器 h2 + p 命中紧贴h2之后的一个p;通用兄弟选择器 h2 ~ p 命中h2之后同层的全部p。合理利用组合关系可以减少额外class的添加,让HTML更语义化。下面示例展示子选择器与相邻兄弟的差异:
/* 仅直接子级生效 */
.nav > li {
padding: 8px;
}
/* h2后面紧邻的第一个p变红 */
h2 + p {
color: #c00;
}
属性选择器与结构伪类
CSS3属性选择器支持更细粒度的匹配。除了基础的 [attr] 存在性匹配,还有 [attr=value] 精确匹配、[attr~=value] 单词列表包含、[attr^=value] 前缀匹配、[attr$=value] 后缀匹配以及 [attr*=value] 子串匹配。默认情况下这些值匹配区分大小写,但可在方括号内追加 i 标志实现不区分大小写,例如 [type=text i]。属性选择器非常适合处理带有一致命名规律但无统一class的表单控件。
结构伪类则是CSS3的一大亮点。:nth-child(n) 按照父元素下所有子节点排序计数,而 :nth-of-type(n) 只在同类标签中计数,这是最容易混淆的一点。比如 li:nth-child(2) 要求该li必须是父级的第二个子节点,若前面有非li元素则不会命中;li:nth-of-type(2) 则只管li序列中的第二者。此外 :first-child、:last-child、:only-child 也常被用来做列表首尾样式优化。以下代码演示两种伪类的区别:
<div class="box"> <p>段落</p> <li>项目一</li> <li>项目二</li> </div>
/* 不会命中任何li,因为li不是父级第二个子节点 */
li:nth-child(2) { color: blue; }
/* 命中“项目二”,它是第二个li */
li:nth-of-type(2) { font-weight: bold; }
另一个常用结构是 :not() 否定伪类,它接受简单选择器作为参数,排除符合规则的节点。比如 li:not(.active) 选中所有不带active类的li。需要注意 :not() 本身不提升优先级,其权重由内部选择器决定。结合属性与结构伪类,能用纯CSS实现很多过往需要JS参与的显示逻辑。
状态伪类与伪元素选择器
状态伪类用于响应用户交互或表单状态。:hover 在指针悬停时触发,:focus 在元素获得焦点时触发,:checked 命中被选中的单选或复选框,:disabled 与 :enabled 分别匹配禁用与可用表单控件。CSS3还引入了 :required、:optional、:valid、:invalid 等表单校验相关伪类,可以在不写脚本的情况下给用户即时反馈。这些伪类极大增强了样式层的行为表达能力。
伪元素选择器以双冒号语法表示,包括 ::before、::after、::first-line、::first-letter、::selection 等。它们创建的是不在DOM中但可被样式控制的抽象节点。::before 与 ::after 必须配合 content 属性出现,常用来插入装饰性图标或清除浮动。与伪类不同,伪元素实际上生成了新盒子,因此不能像普通元素那样被JS直接选取。下面示例用伪元素给外链添加标记:
a[href^="http"]::after {
content: "↗";
margin-left: 2px;
color: #888;
}
综合来看,CSS3选择器体系从基础匹配延伸到结构、属性、状态与抽象节点多个层面。掌握它们的权重规则与匹配边界,可以避免样式冲突,也能减少对JavaScript和冗余class的依赖。建议在项目中逐步用结构伪类替代部分JS逻辑,用属性选择器统一处理组件变体,从而让样式表更简洁、更易读。