CSS @layer 实践:样式优先级别再靠选择器硬怼
CSS @layer 实践:样式优先级别再靠选择器硬怼
CSS 项目变大后,样式冲突经常变成玄学。一个按钮在页面 A 正常,到页面 B 被全局样式覆盖;组件库样式、业务样式、工具类样式互相抢优先级。很多人会继续加选择器、加!important,最后样式表越来越难维护。
@layer提供了更清晰的级联分层方式。它不能解决所有 CSS 问题,但能让优先级从“谁选择器更狠”变成“谁属于哪一层”。
一、先设计样式层级
flowchart TD A[reset] --> B[tokens] B --> C[base] C --> D[components] D --> E[utilities] E --> F[overrides]层级顺序应该在入口文件里声明清楚。越靠后的 layer 优先级越高,即使选择器不复杂,也能覆盖前面的层。
二、声明 layer 顺序
@layer reset, tokens, base, components, utilities, overrides; @layer reset { *, *::before, *::after { box-sizing: border-box; } } @layer components { .button { border-radius: var(--radius-control-md); } }这样组件样式和工具类样式的关系是显式的。团队不用猜到底哪个文件后加载。
三、工具类要放在合适层
如果项目里有 Tailwind 或自定义 utilities,要明确它和组件层的关系。有些团队希望工具类能覆盖组件,有些团队希望组件保持稳定。
@layer utilities { .mt-4 { margin-top: 16px; } .text-muted { color: var(--color-text-muted); } }关键是统一。不要一部分工具类覆盖组件,另一部分又被组件覆盖。
四、不要把 layer 当万能药
@layer管的是级联顺序,不负责解决命名混乱、Token 缺失或组件边界不清。层级太多也会让理解成本上升。
recommended_layers: reset base components utilities overrides大多数项目 4 到 6 层足够。每一层都要有明确用途,避免把所有临时修复都塞进 overrides。
迁移时不要一次性重写全部样式。可以先在入口声明 layer 顺序,再把 reset、组件库和业务 overrides 分批迁入。每迁一层,就跑一次视觉回归,确认优先级变化没有影响关键页面。
layer_migration: step1: declare layer order step2: move reset and base step3: move component styles step4: move utilities step5: audit overrides这样做比大爆炸式重构稳很多,也更容易定位哪一层引入了变化。
五、总结
CSS@layer能把样式优先级治理得更清楚。先声明 reset、base、components、utilities、overrides 等层级,再把样式放到正确位置。
别再靠选择器硬怼优先级。级联顺序被显式管理后,样式系统会安静很多。
@layer最适合解决团队协作中的优先级约定问题。约定写在 CSS 里,比写在文档里更不容易被忘记。
