Skip to content

CSS 选择器与优先级

CoreCSS Fundamentals

选择器决定 "样式应用在哪",优先级决定 "冲突时谁赢"。这两者构成了 CSS 层叠(Cascade)机制的核心。


一、🎯 基础选择器

1.1 元素选择器(Element Selector)

直接使用 HTML 标签名,选中页面上 所有 该类型元素:

css
h2 {
  color: red;
}

所有 <h2> 元素的文本都会变红,是 最不具体 的选择方式。

1.2 类选择器(Class Selector)

使用 .(点号)+ 类名,选中所有拥有该 class 属性的元素:

css
.red-text {
  color: red;
}
html
<h2 class="red-text">标题</h2>
<p class="red-text">段落</p>
  • 同一个类可以应用到 不同类型 的多个元素上
  • 一个元素可以有 多个类,用空格分隔:class="bold large"

1.3 ID 选择器(ID Selector)

使用 #(井号)+ ID 名,选中具有该 id 属性的 唯一 元素:

css
#main {
  color: orange;
}
html
<h2 id="main">唯一标题</h2>

ID 的唯一性

在同一个 HTML 文件中,每个 ID 只能使用 一次。这是 ID 与 class 的本质区别。

1.4 属性选择器(Attribute Selector)

使用 [attribute][attribute="value"] 精确匹配:

css
/* 选中所有带 draggable 属性的 p 元素 */
p[draggable] {
  color: purple;
}

/* 选中 draggable="false" 的 p 元素 */
p[draggable="false"] {
  color: gray;
}

1.5 通配符选择器(Universal Selector)

使用 * 选中 所有 元素:

css
* {
  text-align: center;
}

二、🔗 组合选择器(Combining Selectors)

2.1 分组选择器(Group)— 逗号 ,

对多个选择器应用 相同 样式,用逗号分隔:

css
h1, h2 {
  color: blueviolet;
}

含义:选中所有 <h1> 所有 <h2>,应用同一规则。

2.2 子选择器(Child)— >

选中某元素的 直接子元素(只看一层深度):

css
.box > p {
  color: firebrick;
}
html
<div class="box">
  <p>✅ 会被选中(直接子元素)</p>
  <ul>
    <li><p>❌ 不会被选中(孙元素)</p></li>
  </ul>
</div>

2.3 后代选择器(Descendant)— 空格

选中某元素 内部任意深度 的后代元素:

css
.box li {
  color: blue;
}

不论 <li> 嵌套多深,只要它在 .box 内部就会被选中。

Child vs Descendant

  • > → 只看 一层(父 → 子)
  • 空格 → 看 任意深度(祖先 → 后代)

一般推荐使用后代选择器(空格),因为它更灵活。除非你明确只想限定直接子元素。

2.4 链式选择器(Chaining)— 无空格

将多个选择器 直接拼接(无空格),表示同一个元素必须 同时满足 所有条件:

css
li.done {
  color: seagreen;
}

含义:选中 既是 <li> 元素 又拥有 done 的元素。

html
<li class="done">✅ 被选中</li>
<li>❌ 没有 done 类</li>
<p class="done">❌ 不是 li 元素</p>

元素选择器必须在最前面

当链式中包含元素选择器时,元素名必须写在最前面

css
/* ✅ 正确 */
li.done#first { ... }

/* ❌ 错误 —— .doneli 会被解读为类名 "doneli" */
.doneli { ... }

2.5 组合使用

以上方法可以 混合使用

css
/* 在 ul 后代中,找到同时是 p 元素且有 done 类的元素 */
ul p.done {
  font-size: 0.5rem;
}

三、🌊 层叠机制(The Cascade)

当多条 CSS 规则 冲突(作用于同一元素的同一属性)时,浏览器按照 四个层级 逐级判定:

❶ Position(位置) → ❷ Specificity(特异性) → ❸ Type(类型) → ❹ Importance(!important)

下层覆盖上层,越往后优先级越高。

3.1 Position(位置)

同等条件下,后出现的规则覆盖先出现的

css
li {
  color: red;    /* ← 先应用 */
  color: blue;   /* ← 后应用,最终生效 */
}

在同一个 CSS 文件中,规则的 书写顺序 越靠后,优先级越高。

3.2 Specificity(特异性)

选择器越 具体,优先级越高。从低到高:

优先级选择器类型示例权重
最低元素选择器li0-0-1
类选择器.done0-1-0
属性选择器[draggable]0-1-0
最高ID 选择器#main1-0-0
css
/* 特异性: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 属性)
html
<!-- 即使外部 CSS 中用了 #id 选择器(特异性高),
     Inline 样式仍然胜出(Type 层级更高) -->
<h1 id="title" style="color: blue;">标题</h1>

3.4 Importance(!important

在属性值后加 !important,该规则将 无条件胜出

css
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

六、📚 参考资源


← 返回 Web 开发研究