CSS Handbook · 自定义属性与现代函数

第十章 / 10.3 @layer 层叠层与 @scope

第十章 · 10.3 节

@layer 层叠层与 @scope


回到 1.2 节留下的伏笔:当项目规模变大、样式来源变多(重置样式、组件库、页面覆写、第三方样式),仅凭选择器优先级早晚已经很难管理覆盖关系。@layer@scope 是 CSS 为解决这一"规模化"问题给出的现代方案。

大型项目中的优先级困局

设想这样的场景:组件库定义了 .button 的样式,页面级代码想要覆盖它的颜色,却因为组件库内部用了更具体的选择器(比如 .card .button),导致页面样式怎么写都覆盖不掉——只能被迫升高选择器权重甚至滥用 !important,样式表因此逐渐失控。

@layer 基本用法

@layer 把样式划分进"层叠层",层与层之间有明确的优先级顺序,与每层内部的选择器权重完全无关——后声明的层整体覆盖先声明的层,哪怕后者选择器权重再低。

/* 第一步:声明层的顺序(越靠后优先级越高) */
@layer reset, base, components, utilities;

/* 第二步:把样式放进对应的层 */
@layer reset {
  * { margin: 0; }
}
@layer components {
  .card .button { color: gray; } /* 权重更高,但层更低 */
}
@layer utilities {
  .button { color: teal; } /* 权重更低,但层更高 —— 生效 */
}
关键规则任何显式分层的规则,优先级都高于未分层的普通规则——但都低于内联样式与 !important(且 !important 在层间的覆盖顺序是反过来的:先声明的层里的 !important 反而更高)。

层的声明顺序即优先级顺序

第一次遇到某个层名时就确定了它在层叠顺序中的位置,之后可以在文件的任意位置多次追加同名 @layer 块,内容会合并,但顺序不会改变——这让"先规划层级结构,再分批填充内容"成为可能,非常适合拆分到多个 CSS 文件维护。

/* reset.css */
@layer reset { ... }

/* components.css,晚于 reset.css 加载也没关系 */
@layer components { ... }

@scope:限定样式作用范围

@scope 解决的是另一个问题:让一组样式只在指定的 DOM 子树内生效,不会"泄漏"影响到无关区域,天然适合给可能被嵌套复用的组件加边界:

@scope (.card) to (.card-nested) {
  p { color: #5c5872; }
}
/* 只作用于 .card 内部的 p,且遇到 .card-nested 就停止向下作用 —— 避免影响卡片内嵌套的另一个卡片 */

全书回顾

从最基础的标签选择器,到能够表达复杂组件关系的伪类组合;从静态的盒模型,到能响应视口与容器变化的 Flexbox、Grid 与媒体/容器查询;再到颜色、渐变、动效与变量系统——这七章内容构成了现代 CSS 的核心骨架。真正的熟练,来自把它们组合起来解决具体问题:下一步,不妨挑一个你正在做(或想做)的页面,试着只用本书讲过的知识,从零把它搭建出来。