源本科技 | 码上会

CSS 特异性

2026/03/06
15
0

学习目标

  • 理解 CSS 特异性的核心概念及其在样式冲突中的作用

  • 掌握不同选择器(行内、ID、类、元素)的特异性层级关系

  • 学会计算和比较特异性值,预测最终应用的样式

  • 了解当特异性相同时,源代码顺序对样式应用的影响


正文内容

什么是特异性

CSS 特异性是浏览器用来确定当多条规则针对同一元素时,哪条 CSS 样式应该被应用的一套规则体系。简单来说,当多个样式规则发生冲突时,特异性值更高的规则将优先生效。

核心原则如下:

  • 行内样式拥有最高的特异性

  • ID 选择器的优先级高于类、属性和元素选择器

  • 类选择器的优先级高于元素和伪元素选择器

  • 当特异性值相等时,后编写的规则生效

样式来源与优先级

为了直观理解不同来源样式的优先级,我们来看一个综合示例。该示例展示了外部样式表、内部样式表和行内样式之间的覆盖关系。

<!DOCTYPE html>
<html>
<head>
    <!-- 引入外部样式表 -->
    <link rel="stylesheet" type="text/css" href="external.css">
    
    <!-- 内部样式表 -->
    <style type="text/css">
        h1 {
            background-color: red;
            color: white;
        }

        h2 {
            color: blue;
        }
    </style>
</head>

<body>
    <!-- 内部 CSS 覆盖外部 CSS -->
    <h1>内部 CSS 覆盖外部 CSS</h1>
    
    <!-- 行内 CSS 覆盖内部 CSS -->
    <h2 style="color: green;">行内 CSS 覆盖内部 CSS</h2>
</body>
</html>

对应的外部样式文件 external.css 内容如下:

/* external.css */
h1 {
    background-color: lightgreen;
}

h2 {
    color: pink;
}

现象解析:

  1. <h1> 标签最终显示红色背景。虽然外部样式定义为浅绿色,但内部样式表中定义的 h1 规则具有相同的特异性(都是元素选择器),由于内部样式在 HTML 文档中后加载,因此覆盖了外部样式。

  2. <h2> 标签最终显示绿色文字。行内样式的特异性远高于内部样式表中的元素选择器,因此直接覆盖了内部定义的蓝色。

特异性三大规则

1. 行内 CSS

行内 CSS 是通过 HTML 元素的 style 属性直接应用的样式。

  • 特点:拥有最高的特异性。

  • 效果:无论内部或外部 CSS 如何定义,行内样式都会优先覆盖它们(除非使用 !important 标记在其他地方,但行内本身权重极高)。

2. 内部 CSS

内部样式表定义在 HTML 文档的 <style> 标签内。

  • 特点:其特异性完全取决于所使用的选择器类型(ID > 类 > 元素)。

  • 效果:当选择器特异性相同时,内部 CSS 会覆盖外部 CSS,这是因为它们在文档流中出现得更晚,而非因为它们是“内部”的。

3. 外部 CSS

外部 CSS 编写在独立的 .css 文件中,并通过 <link> 标签引入。

  • 特点:主要用于保持多页面风格一致。其特异性同样取决于选择器本身。

  • 误区澄清:外部 CSS 的特异性并不天然低于内部 CSS。如果外部和内部使用了完全相同的选择器(例如都是 .class-name),它们的特异性值是相等的。此时,谁后加载谁生效。

重要提示:
特异性主要由选择器本身决定,而不是由样式定义的位置(<style> 标签内还是外部文件)决定。只有当选择器成分完全相同导致特异性相等时,HTML 文档中的引入顺序(即代码书写顺序)才会成为决定性因素。对于通用选择器(如 *)和继承来的样式,其特异性最低。

特异性层级结构

每个选择器在特异性层级中都占据特定的位置。我们可以将其划分为四个主要等级:

优先级

描述

示例

行内样式

最高优先级,通过 style 属性直接应用

<div style="color: red;">

ID 选择器

第二高优先级,通过元素唯一的 id 属性识别

#header, #main-content

类、伪类、属性

中等优先级,通过类名、伪类(如 :hover)或属性选择器定位

.btn, a:hover, [type="text"]

元素和伪元素

最低优先级,应用于 HTML 标签本身或伪元素

div, p, ::before, ::after

为了更清晰地展示这一层级关系,我们可以通过以下流程图来理解浏览器的判断逻辑:

综合示例

下面是一个包含多种选择器混合使用的完整示例,展示了不同优先级在实际代码中的表现。

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        /* 元素选择器:优先级最低 */
        h1 {
            background-color: red;
            color: white;
        }

        /* ID 选择器:优先级高 */
        #second {
            background-color: black;
            color: white;
        }

        /* 类选择器:优先级中等 */
        .third {
            background-color: pink;
            color: blue;
        }

        /* 仅控制颜色的 ID 选择器 */
        #second1 {
            color: blue;
        }

        /* 仅控制颜色的类选择器 */
        .third1 {
            color: red;
        }
    </style>
</head>

<body>
    <!-- 
      分析:
      1. 拥有 ID "second" 和 类 "third"。
      2. ID 优先级 > 类优先级 > 元素优先级。
      3. 背景色:#second (黑) 覆盖 .third (粉) 覆盖 h1 (红)。
      4. 文字颜色:#second (白) 覆盖 .third (蓝) 覆盖 h1 (白,同色无变化)。
    -->
    <h1 id="second" class="third">
        ID 选择器拥有最高优先级
    </h1>

    <!-- 
      分析:
      仅受 h1 元素选择器控制,显示红色背景,白色文字。
    -->
    <h1>
        元素选择器优先级最低
    </h1>

    <!-- 
      分析:
      拥有类 "third"。
      类优先级 > 元素优先级。
      背景色:.third (粉) 覆盖 h1 (红)。
      文字颜色:.third (蓝) 覆盖 h1 (白)。
    -->
    <h1 class="third">
        类选择器优先级高于元素选择器
    </h1>

    <!-- 
      分析:
      1. 拥有行内样式 style="color: green;"。
      2. 行内样式优先级最高,直接覆盖所有其他颜色定义。
      3. 尽管有 ID 和 类,但在颜色属性上,行内样式胜出。
    -->
    <h2 style="color: green;" 
        id="second1"
        class="third1">
        行内 CSS 拥有绝对最高优先级
    </h2>
</body>
</html>

总结

  • 特异性计算核心:浏览器的样式应用决策基于选择器的权重,权重顺序为:行内样式 > ID 选择器 > 类 / 伪类 / 属性选择器 > 元素 / 伪元素选择器。

  • 位置无关性:外部样式表和内部样式表的特异性计算规则是一致的。如果选择器相同,后加载的样式覆盖先加载的样式。

  • 平局处理:当两个或多个选择器的特异性完全相同时,CSS 遵循“后来居上”原则,即代码中最后出现的规则生效。

  • 通用选择器:通用选择器(*)以及继承属性的特异性极低,最容易被其他规则覆盖。


思考题

  1. 如果一个元素同时被 ID 选择器(#nav)和三个类选择器(.menu.active.large)选中,哪个规则的背景色会生效?为什么?

  2. 在什么情况下,写在外部 CSS 文件中的规则可以覆盖写在 HTML 内部 <style> 标签中的规则?请举例说明。

  3. 假设你有以下 CSS 规则:div.container p.container p。如果它们作用于同一个段落元素,且没有其他干扰因素,哪一个特异性更高?请尝试拆解它们的权重构成。