chrome 119+才稳定支持原生css嵌套,112–118为实验阶段且默认禁用或解析失败,低于112(如105)完全不识别&和@nest,整条规则被静默丢弃。

Chrome 119以下版本根本不认&和@nest
原生CSS嵌套在 Chrome 119 才稳定启用,112–118 是实验阶段,且默认禁用或部分解析失败;低于 112 的版本(如 Chrome 105)压根不识别 & 或 @nest,整条规则被静默丢弃——DevTools Styles 面板里直接看不到,也不报错、不警告。
这不是“样式没生效”,而是 CSS 解析器在词法分析阶段就跳过了整个块。你写的 .card { @nest & h2 { color: red; } } 在 Chrome 116 下可能只保留 .card { },里面的内容全没了。
- Chrome 118 及以下:即使启用了
chrome://flags#css-nesting,@nest仍可能被忽略,尤其当它出现在嵌套层级较深或含复合伪类时 - 构建工具(如 Vite、Webpack)若未配
postcss-nesting,本地开发用 Chrome 120 能跑,但打包后发到线上,低版本用户看到的是空规则 - 别依赖 UA 字符串判断——用户可能用企业定制版 Chrome,版本号是 115 但实际内核冻结在 104,
@supports也查不出来
@supports 检测对原生嵌套完全无效
@supports (nesting: true) 不是标准语法,浏览器会直接忽略整条 @supports 规则;@supports (selector(&)) 也不存在,CSS 标准里没有 selector() 这种函数。
真正能用的检测只有 JS 层的 CSS.supports('nesting', 'true'),但它在 IE11、旧版 QQ 浏览器、部分安卓 WebView 中会抛错或返回 undefined,不能作为首层判断依据。
- 第一层必须先判
typeof CSS === 'undefined' || !CSS.supports,为真则走全量降级路径 - 第二层再调
CSS.supports('nesting', 'true'),但要注意:Firefox 124+ 默认关闭该特性,需用户手动开启layout.css.nesting.enabled,JS 检测返回false是正常行为 - 不要写
@supports not (nesting: true) { ... }——这句本身就不合法,所有浏览器都会跳过
降级必须靠构建时转译,不是运行时 fallback
原生嵌套没有“优雅降级”机制。浏览器不认识 @nest 就不解析后续内容,不会回退到父选择器下写普通 CSS。唯一可靠路径是构建阶段把 @nest 和 & 转成标准 CSS。
推荐用 postcss-nesting(不是 postcss-custom-properties),它能正确处理 @nest & > li a:hover 这类复杂结构,并兼容 BEM 修饰符写法。
- 确保插件在 Autoprefixer 之前执行,否则
@nest块可能被压缩工具提前剔除 - Vite 用户需显式配置
css.postcss.plugins,默认不启用postcss-nesting - Webpack + css-loader 用户要检查
exportOnlyLocals: false,否则&可能被误当作局部变量名处理 - 禁止混用:Sass 编译后的 CSS 里再套
@nest,会导致双重嵌套解析失败
最常被忽略的细节:& 的位置和空格
即使构建转译正常,手写时一个空格就会让整块失效:&:hover 合法,& :hover(中间有空格)就变成后代选择器,语义彻底偏移;&.active 合法,.active & 直接无效。
更隐蔽的是 @nest 必须跟完整选择器:@nest & + section 错误(缺左侧上下文),应写成 @nest article & + section;@nest & ul { @nest & li { } } 是非法嵌套,原生不支持多层 @nest。
- 所有
&必须紧贴@nest后或规则开头,不能缩进、不能换行、不能有前导空格 -
&::before正确,& ::before错误(空格导致变成.btn ::before,虽常能渲染但逻辑已失控) - 媒体查询可内联在嵌套块里,但不能塞进
@nest内部:@nest & @media (max-width: 600px) { }是语法错误
@nest 或孤立的 &,说明转译链断了——这时候用户打开页面,看到的不是旧样式,而是没样式。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











