第十章 · 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 的核心骨架。真正的熟练,来自把它们组合起来解决具体问题:下一步,不妨挑一个你正在做(或想做)的页面,试着只用本书讲过的知识,从零把它搭建出来。