就近原则本质是层叠顺序中特异性相等时按声明顺序生效的fallback机制;@scope通过限定作用域使外部同名规则不参与层叠计算,实现作用域内声明优先。

就近原则不是“离得近就赢”,而是浏览器在**多个匹配规则中选一个生效时**,按声明位置(源码顺序)和作用域边界共同决定的 fallback 机制;@scope 出现后,“就近”不再只看 CSS 文件里谁写在后面,还要看谁被显式框定在更小的作用域内。
就近原则的本质是层叠顺序(cascade order),不是物理距离
很多人以为把 style 写在 <div> 标签里就“更近”,其实关键在于:浏览器解析 CSS 时,先收集所有匹配的选择器,再按「来源 → 重要性 → 特异性 → 声明顺序」逐级比对。所谓“就近”,仅在特异性(specificity)完全相等时才起效——比如两个 <code>.btn 规则,后声明的覆盖先声明的。
- 特异性不同时,
#header .btn(0,1,1,0)永远压过.btn(0,0,1,0),哪怕后者写在后面 - 使用
@scope(.card)后,其内部的.title和外部同名类选择器特异性相同(都是 0,0,1,0),此时才真正触发“作用域内声明优先”的就近逻辑 -
:scope伪类本身不提升权重,它只是让选择器锚定到 scope 容器上,避免意外继承或穿透
@scope 规则如何改变“就近”的判定范围
@scope 不是 selector,而是一个作用域声明块;它不会让里面的选择器变“更重”,但会切断外部同名规则的匹配路径。换句话说:没被 @scope 包住的样式,根本不会参与该容器内元素的层叠计算。
- 外部定义的
.title { color: red; }对<div class="card"><h2 class="title">...</h2></div>无效,除非该.title同时匹配 scope 外的其他上下文 - scope 内部的
.title { color: blue; }只和 scope 内其他规则比先后,不和全局.title比权重 - 嵌套
@scope时,内层 scope 的规则优先于外层 scope 的同名规则,这属于“作用域嵌套深度”带来的隐式就近优势
为什么用 @scope 后还被外部样式覆盖?常见漏点
目前(2026 年中)@scope 仍属实验性特性,主流浏览器支持依赖 chrome 124+、firefox 126+,且需开启 flag 或使用 polyfill。即使语法正确,以下情况仍会导致失效:
- HTML 中未给 scope 容器设置对应 class/id:
@scope(.card)要求存在<div class="card">,不能只靠 JS 动态添加 class <li>scope 块写在 <code><style></style>外部(如单独 CSS 文件),部分构建工具(如 PostCSS 默认配置)会直接丢弃未知 at-rule - 误以为
@scope能限制继承样式——它只约束选择器匹配,不影响color、font-size等可继承属性的向下传递 - 混用
!important:scope 内加了!important的规则,依然会被 scope 外同样带!important且特异性更高的规则击败
真正需要关注的不是“哪个更近”,而是“哪个能匹配进来”;@scope 把问题从“怎么压过别人”转向“怎么把自己关进盒子”,这是现代 CSS 作用域设计的关键转向——复杂点在于,你得同时管好 HTML 结构、CSS 作用域声明、构建流程三端一致性。











