CSS 选择器与优先级
CoreCSS Fundamentals选择器决定 "样式应用在哪",优先级决定 "冲突时谁赢"。这两者构成了 CSS 层叠(Cascade)机制的核心。
一、🎯 基础选择器
1.1 元素选择器(Element Selector)
直接使用 HTML 标签名,选中页面上 所有 该类型元素:
h2 {
color: red;
}所有 <h2> 元素的文本都会变红,是 最不具体 的选择方式。
1.2 类选择器(Class Selector)
使用 .(点号)+ 类名,选中所有拥有该 class 属性的元素:
.red-text {
color: red;
}<h2 class="red-text">标题</h2>
<p class="red-text">段落</p>- 同一个类可以应用到 不同类型 的多个元素上
- 一个元素可以有 多个类,用空格分隔:
class="bold large"
1.3 ID 选择器(ID Selector)
使用 #(井号)+ ID 名,选中具有该 id 属性的 唯一 元素:
#main {
color: orange;
}<h2 id="main">唯一标题</h2>ID 的唯一性
在同一个 HTML 文件中,每个 ID 只能使用 一次。这是 ID 与 class 的本质区别。
1.4 属性选择器(Attribute Selector)
使用 [attribute] 或 [attribute="value"] 精确匹配:
/* 选中所有带 draggable 属性的 p 元素 */
p[draggable] {
color: purple;
}
/* 选中 draggable="false" 的 p 元素 */
p[draggable="false"] {
color: gray;
}1.5 通配符选择器(Universal Selector)
使用 * 选中 所有 元素:
* {
text-align: center;
}二、🔗 组合选择器(Combining Selectors)
2.1 分组选择器(Group)— 逗号 ,
对多个选择器应用 相同 样式,用逗号分隔:
h1, h2 {
color: blueviolet;
}含义:选中所有 <h1> 和 所有 <h2>,应用同一规则。
2.2 子选择器(Child)— >
选中某元素的 直接子元素(只看一层深度):
.box > p {
color: firebrick;
}<div class="box">
<p>✅ 会被选中(直接子元素)</p>
<ul>
<li><p>❌ 不会被选中(孙元素)</p></li>
</ul>
</div>2.3 后代选择器(Descendant)— 空格
选中某元素 内部任意深度 的后代元素:
.box li {
color: blue;
}不论 <li> 嵌套多深,只要它在 .box 内部就会被选中。
Child vs Descendant
>→ 只看 一层(父 → 子)- 空格 → 看 任意深度(祖先 → 后代)
一般推荐使用后代选择器(空格),因为它更灵活。除非你明确只想限定直接子元素。
2.4 链式选择器(Chaining)— 无空格
将多个选择器 直接拼接(无空格),表示同一个元素必须 同时满足 所有条件:
li.done {
color: seagreen;
}含义:选中 既是 <li> 元素 又拥有 done 类 的元素。
<li class="done">✅ 被选中</li>
<li>❌ 没有 done 类</li>
<p class="done">❌ 不是 li 元素</p>元素选择器必须在最前面
当链式中包含元素选择器时,元素名必须写在最前面:
/* ✅ 正确 */
li.done#first { ... }
/* ❌ 错误 —— .doneli 会被解读为类名 "doneli" */
.doneli { ... }2.5 组合使用
以上方法可以 混合使用:
/* 在 ul 后代中,找到同时是 p 元素且有 done 类的元素 */
ul p.done {
font-size: 0.5rem;
}三、🌊 层叠机制(The Cascade)
当多条 CSS 规则 冲突(作用于同一元素的同一属性)时,浏览器按照 四个层级 逐级判定:
❶ Position(位置) → ❷ Specificity(特异性) → ❸ Type(类型) → ❹ Importance(!important)下层覆盖上层,越往后优先级越高。
3.1 Position(位置)
同等条件下,后出现的规则覆盖先出现的:
li {
color: red; /* ← 先应用 */
color: blue; /* ← 后应用,最终生效 */
}在同一个 CSS 文件中,规则的 书写顺序 越靠后,优先级越高。
3.2 Specificity(特异性)
选择器越 具体,优先级越高。从低到高:
| 优先级 | 选择器类型 | 示例 | 权重 |
|---|---|---|---|
| 最低 | 元素选择器 | li | 0-0-1 |
| ↑ | 类选择器 | .done | 0-1-0 |
| ↑ | 属性选择器 | [draggable] | 0-1-0 |
| 最高 | ID 选择器 | #main | 1-0-0 |
/* 特异性:0-1-0(类) */
.first-class { color: green; }
/* 特异性:1-0-0(ID)→ ID 胜出 */
#first-id { color: orange; }特异性计算口诀
把选择器分成三栏:ID — Class/Attribute — Element,分别计数,从左到右比较大小。
3.3 Type(类型)
CSS 的引入方式也有优先级差异:
| 优先级 | 引入方式 |
|---|---|
| 最低 | External(外部样式表) |
| ↑ | Internal(<style> 标签) |
| 最高 | Inline(style 属性) |
<!-- 即使外部 CSS 中用了 #id 选择器(特异性高),
Inline 样式仍然胜出(Type 层级更高) -->
<h1 id="title" style="color: blue;">标题</h1>3.4 Importance(!important)
在属性值后加 !important,该规则将 无条件胜出:
h1 {
color: red !important; /* 最高优先级 */
}谨慎使用
!important 会破坏正常的层叠机制,使代码难以调试和维护。仅在 万不得已 时使用(例如覆盖第三方库的样式)。
四、📊 优先级完整排序
从低到高的完整排序:
Position(同级别下,后写的赢)
↓
Specificity(Element < Class/Attribute < ID)
↓
Type(External < Internal < Inline)
↓
!important(无条件最高)快速判断流程
1. 是否有 !important ? → 有则直接胜出
2. 引入方式是什么? → Inline > Internal > External
3. 选择器的特异性? → ID > Class/Attr > Element
4. 在代码中的位置? → 后出现的覆盖先出现的五、💡 实践要点
| # | 要点 | 说明 |
|---|---|---|
| 1 | 优先使用 类选择器 | 灵活、可复用、特异性适中 |
| 2 | 避免过度使用 ID 选择器 | 特异性太高,容易造成覆盖困难 |
| 3 | 避免 !important | 应该通过合理的选择器组合来解决冲突 |
| 4 | 善用 组合选择器 | 减少额外的 class/ID,保持 HTML 整洁 |
| 5 | 后代选择器优于子选择器 | 除非需要严格限定一层关系 |
| 6 | 链式选择器 元素在前 | li.done ✅,.doneli ❌ |