← 中文资源

简体中文版本

用层叠工具箱调停 CSS 优先级战争

查明哪条规则真正胜出及原因,把优先级量化而非猜测,用 @layer 与 :where 终结军备竞赛。

阅读英文原文

目标

蓝色按钮打赢红色 !important 必有可计算的原因:层叠规则给参赛者排了序,DevTools 的样式面板会点名胜者。把逐选择器的军备竞赛换成一次声明的层顺序,未来每个冲突都变成查表而非决斗。先读胜负、再算三元组、再拆除 !important、最后用 @layer 与 :where 立约。

步骤要点

  1. 在样式面板选中争议元素:被划掉的规则按排名列在胜者下方,悬停每个选择器读它的 (a,b,c) 优先级三元组。
  2. 用小脚本手工计算各选择器的三元组,与 DevTools 读数互相印证,把胜负变成算术。
  3. 拆军备竞赛:一次协调的 PR 让双方同时撤掉争议属性上全部 !important,为结构性修复清场。
  4. 用层叠立约:声明 reset、theme、components、utilities、overrides 五层顺序,utilities 永远赢 components 是层序使然,reset 里用 :where(a) 保持零优先级礼貌地输。
  5. 验证:重载后按钮呈设计色,切换 .text-red 时工具类按层序胜出,全仓 !important 计数降到接近零。

排错提示

框架的样式压在你的层之上是因为未分层样式胜过所有层,用 import layer() 把框架样式装进低优先层,或在 overrides 里一次性匹配它的优先级;内联样式与 JS 设置的 style 打败一切,正常手段只有样式表里带 !important 能赢,优先移除内联,确实躲不开就在 overrides 层里留一处有文档的例外;手算三元组与 DevTools 不一致时查伪类与伪元素::hover 计 class 级而 ::before 计元素级,这是最常见的数错。

适用边界

层叠层需要全部现代浏览器支持与团队对层名的纪律,无文档的层只会制造新谜团;优先级算术解释谁赢不解释设计意图,层才编码意图,所以两样都得进工具箱。

代码示例

the duel, decoded:
  .card .btn      { color: blue; }             (0,2,0)
  .btn.primary    { color: red; !important }   (0,2,0) + important
  winner: .card .btn?? no -- BOTH !important? higher (a,b,c) wins
  actual winner in DevTools: #app .card .btn  (1,2,0)
  -> someone's ancestor id joined the fight silently

the treaty:
  @layer reset, theme, components, utilities, overrides;
  conflicts now resolved by layer order, !important count: 0