设计配色 · 排版打印

CSS 优先级计算

选择器 specificity 评分

✓本地处理 · 不上传 ✓免费 · 无需登录 ✓无次数限制 累计 123 次使用
a ID · b 类/属性/伪类 · c 元素/伪元素 · 逐 token 拆解 纯本地计算
评 分 档a , b , c · 字典序比较
a ID 选择器 #id · 每个 +1,权重最高
b 类 / 属性 / 伪类 .cls [attr] :hover · 每个 +1
c 元素 / 伪元素 div ::before · 每个 +1;* 不计
对 照 梯 度点击填入 · 由低到高
速 查 规 则Rules
·
行内样式记为 (1,0,0,0) 的独立最高档,压过任何选择器(本工具以四元首位说明,选择器恒为三元 a,b,c)。
·
!important 跳出特异性体系,覆盖一切(除非另一条也 !important,则比该层特异性)。
·
:where() 永远计 0;:is() :has() :not() 取括号内最高的那一条参数。
·
:nth-child(An+B of S) 伪类本身计 b,其参数 S 取最高再叠加。
·
两条特异性相等时:后定义者胜(源码顺序靠后覆盖靠前)。
就绪 · 输入选择器即时计算 (a,b,c),逐段拆解贡献
第一节

关于本工具

About

调试一个复杂选择器时,浏览器 DevTools 里 specificity 数值一闪而过,很难确认不同选择器组合的精确权重。这个工具接受 CSS 选择器输入,即时返回按 W3C 规范拆分的 A-B-C-D 四级分值,并显示每条规则的优先级排名。计算完全在浏览器本地完成,不发送任何选择器文本到服务器。

使用场景

壹

重构覆盖样式

前端老项目重构,旧代码里有一堆 `!important` 和深层嵌套的 `#header .nav ul li a` 选择器。新同事接手后,想给某个按钮改颜色,加了个 `.btn-blue`,结果死活不生效。把新旧两条规则贴进工具,一看评分:旧选择器 specificity 是 (0,4,1),新的是 (0,1,0)。瞬间明白不是代码写错,是权重不够。改写成 `#header .btn-blue` 后,优先级压过旧规则,十分钟解决半天排查。

贰

排查样式冲突

开发一个商品列表页,A 模块要求所有 `.price` 显示红色,B 模块要求 `.price` 显示绿色。上线后发现 B 模块的 `.price` 始终是红色。用工具分别计算两条规则的 specificity:A 是 (0,1,0),B 是 (0,2,0)。B 的类名多了一个父级,权重更高,理论上应生效。检查后发现 B 的 CSS 文件加载顺序在 A 之前,被 A 的同权重规则覆盖。调整加载顺序后,B 模块颜色正确,无需改选择器结构。

叁

调试第三方组件

项目用了 Element Plus 表格组件,想覆盖默认的表头背景色。写了个 `.my-table .el-table__header th { background: #f0f0f0; }`,刷新后没变化。用工具计算:组件自带的样式是 `.el-table th.el-table__cell`,specificity (0,2,1);自定义样式是 (0,2,0),差一个标签选择器权重。把自定义选择器改为 `.my-table .el-table__header th.el-table__cell`,权重升至 (0,3,1),覆盖成功,无需 `!important`。

肆

评审代码规范

团队定了一条规则:选择器 specificity 不得超过 (0,2,0),避免样式难以覆盖。Code Review 时,同事提交了一段 `.page .sidebar .widget .item a`,算出来是 (0,4,0)。用工具截图发到群里,明确告知违规。建议改为 `.widget-item a`,权重降到 (0,1,0),且语义更清晰。从此每次提交前,开发者自己用工具先算一遍,评审效率提升 70%。

伍

教学演示权重

给刚入行的实习生讲 CSS 优先级,口头说「id 选择器权重 100,类 10,标签 1」,对方一脸懵。打开工具,输入 `#header .nav a`,显示 (1,1,1);再输入 `.nav a`,显示 (0,1,1)。对比两行结果,实习生立刻理解「一个 id 就能压过所有类」。又演示 `#header .nav a` 和 `.nav a.active` 的对比,后者 (0,2,1) 仍输给前者。十分钟讲完原本需要一小时的权重课程。

第二节

使用指南

Getting Started

使用步骤

  1. 1在输入框中粘贴或键入 CSS 选择器(如 `.container .item`),下方立即显示 specificity 评分(a-b-c-d 格式)
  2. 2点击「添加选择器」按钮,将当前选择器及其评分加入对比列表,支持多组同时对比
  3. 3在对比列表中点击任一选择器的评分数字,展开该选择器的详细权重分解(行内样式、ID、类、元素各层分值)
  4. 4勾选对比列表左侧复选框后点击「合并计算」按钮,输出组合选择器的最终 specificity 评分

输入输出示例

输入输出说明
div p span0,0,0,3常规:三个元素选择器,验证基础评分规则
#header .nav a:hover0,1,1,1常规:ID、类、伪类、元素混合,验证四元组正确累加
div#main.content[data-type]0,1,2,1常规:属性选择器与类选择器同级,验证属性选择器算入类级
:is(div, span, p)0,0,0,1边界::is() 伪类本身不增加权重,只取参数中最高权重元素(此处全为元素级)
div:not(.hidden)0,0,1,1边界::not() 伪类不计入权重,但内部参数 .hidden 计入类级
*::before0,0,0,1边界:通用选择器 * 不计权重,但 ::before 伪元素算元素级
#a.b .c.d #e0,2,2,0易错:连续类选择器 .b.c 只算一个类级,不会重复累加
div > p + span ~ a0,0,0,4易错:组合器(> + ~)不产生任何权重,仅计算选择器本身

常见错误对照

1.复合选择器忽略空格含义

✗ 错误.container .text
✓ 修复.container.text

空格表示后代选择器,两个独立选择器分别计分;连写表示同一元素的多类名,只计一个类选择器分。混淆会导致 specificity 计算偏差。

2.ID 选择器与属性选择器 [id=...] 混为一谈

✗ 错误[id="main"] { color: red; }
✓ 修复#main { color: red; }

ID 选择器 (#) 的 specificity 为 (0,1,0,0),属性选择器 [id=...] 仅为 (0,0,1,0)。两者匹配相同元素但权重不同,工具按规范严格区分。

3.伪类 :not() 计分规则误解

✗ 错误:not(.error) { margin: 0; }
✓ 修复:not(.error) { margin: 0; } /* 计分含 .error 的权重 */

:not() 本身不计分,但括号内的选择器参与 specificity 计算。上例实际计分来自 .error(类选择器),而非 :not()。

4.通配符 * 被认为有权重

✗ 错误* { box-sizing: border-box; }
✓ 修复/* 通配符 specificity 为 (0,0,0,0) */

CSS 规范明确 * 不贡献任何 specificity 值。许多开发者误以为它至少占一位,导致覆盖规则时出现意外。

5.行内样式与选择器权重混淆

✗ 错误<div style="color: blue"> 与 #id div { color: red } 比较时认为后者更高
✓ 修复行内样式 specificity 为 (1,0,0,0),高于任何选择器组合(除非 !important)

行内样式通过 style 属性直接附加,其权重独立于选择器体系。工具若只计算选择器部分,需明确标注不包含行内样式。

6.!important 被当作选择器权重的一部分

✗ 错误a { color: green !important; } 被计为 (0,0,1,1)
✓ 修复!important 不参与 specificity 数值计算,而是独立覆盖规则

!important 是声明级别标记,非选择器组成部分。工具应仅计算选择器 specificity,!important 需单独说明其覆盖机制。

7.伪元素 ::before 与伪类 :hover 权重相同

✗ 错误::before { content: ''; } 和 :hover { color: red; } 计分不同
✓ 修复两者均为 (0,0,1,0)(伪元素和伪类在 CSS2.1 中同属一层)

CSS2.1 规范将伪元素与伪类归为同一权重层级(c 列),直到 Selectors Level 3 才区分。工具若按旧规范计算会导致结果偏差。

8.组合选择器未按逗号拆分计算

✗ 错误h1, h2.special { color: black; } 整体计分
✓ 修复每条规则独立计分:h1 → (0,0,0,1);h2.special → (0,0,1,1)

逗号分隔的每个选择器是独立规则,工具应分别输出每条 specificity,而非合并计算。

第三节

工作原理

How It Works

核心公式

specificity = (a, b, c) = a×100 + b×10 + c

变量说明

  • aID 选择器的数量
  • b类、属性、伪类选择器数量
  • c元素、伪元素选择器数量

示例

选择器 #header .nav li.active → ID 1 个(a=1),类/属性/伪类 2 个(.nav .active, b=2),元素 1 个(li, c=1)。specificity = 1×100 + 2×10 + 1 = 121。

输入选择器拆分为元素(ID/类/标签/属性)逐项查表计分(a,b,c 三级)输出输入选择器(对比模式)分别计分后比较(a,b,c)输出单选择器模式双选择器对比模式
用户输入 本地处理 输出结果
第五节

常见问题

Q & A
问这个工具支持多个选择器一起算吗?比如 body .container div .text 这种?+
答

支持。直接粘贴完整选择器字符串即可,工具会按 CSS 规范解析出每个组合器(空格、>、+、~)分隔的复合选择器,然后累加所有简单选择器的权重。注意不要混入属性值里的空格——比如 [class~="foo"] 里的空格是属性选择器的一部分,不会被当作后代组合器处理。

问为什么我用 :hover 和 ::before 算出来的分跟书上写的不一样?+
答

CSS 优先级计算分三个等级:ID 选择器(0-1-0)、类/伪类/属性选择器(0-0-1-0)、元素/伪元素选择器(0-0-0-1)。:hover 属于伪类,归第二档;::before 是伪元素,归第三档。如果你看到的书把伪元素和伪类混为一档,那是旧版规范(CSS2.1 之前),本工具按最新 W3C Selectors Level 3 标准执行。

问我试了 !important,为什么结果没显示?+
答

本工具只计算选择器的 specificity 评分,不处理 !important。!important 属于声明级别的权重提升,它会让一条规则覆盖所有同属性普通声明,但选择器本身的分数不变。如果你需要看 !important 的影响,请手动在结果区对比两个选择器的分数,然后记住加了 !important 的那条优先级最高。

问属性选择器比如 [type="text"] 怎么算分?跟类选择器一样吗?+
答

一样。属性选择器(包括 [attr]、[attr=value]、[attr~=value] 等所有变体)在 CSS 规范中与类选择器、伪类同属第二档(0-0-1-0),每个算 1 分。注意:属性选择器不区分大小写修饰符如 i 或 s 不影响分数,它们只是匹配模式,不是额外选择器。

问这个工具能算 :is() 和 :where() 里面的选择器吗?+
答

可以。:is() 和 :where() 是 CSS Selectors Level 4 新增的伪类,本工具已支持。:is() 取参数列表中最高分作为整个伪类的分数;:where() 则始终计 0 分(它被设计为不增加优先级)。例如 :is(.a, #b) 按 #b 的 1-0-0 算,而 :where(.a, #b) 算 0-0-0。注意浏览器对 :is() 的支持率已超 95%,但旧项目慎用。

问为什么我输入 * 通配符,结果不是 0?+
答

通用选择器 * 的分数确实是 0-0-0,本工具会正确显示为 0。如果你看到非零结果,请检查是否误写了空格或多余字符——比如 "* " 末尾多一个空格会被解析成 "* "(通用选择器加空格),空格本身不是选择器,但若你输入 "* .class" 则变成两个选择器,工具会按组合处理。单独输入 * 一定得 0。

问这个工具能算内联样式吗?我在 style 属性里写的。+
答

不能。内联样式(style="color: red")的优先级是由 HTML 规范定义的,它不属于 CSS 选择器体系,而是独立在 1-0-0-0 之上。本工具只解析 CSS 选择器字符串,不解析 HTML 属性。如果你要对比内联样式与某个选择器的优先级,记住:任何选择器(包括 #id 叠加)都无法覆盖内联样式,除非用 !important。

问我把选择器贴进去点计算没反应,怎么回事?+
答

常见原因有三个:一是选择器里混了中文标点(如逗号用了全角,CSS 只认半角);二是选择器以空格开头或结尾,工具会尝试自动 trim,但如果你输入了多个连续空格,解析器可能报错;三是用了浏览器私有前缀如 ::-webkit-scrollbar,本解析器不支持非标准伪元素。建议先复制一段标准 CSS 选择器测试,确认工具能正常响应。

隐私保证所有计算与处理均在你的浏览器本地完成,输入数据不会上传服务器,也不会保存或共享。

↑↓选择 ↵打开 ⌘+↵新窗口 esc关闭