原生CSS嵌套仅Chrome 119+、Edge 119+、Safari 17.4+稳定支持,Firefox仍实验中;旧版浏览器静默忽略整条规则,须用postcss-nesting预处理或双写+@supports分流降级。

原生 CSS Nesting(嵌套语法)在 Chrome 116+、Firefox 119+、Safari 17.4+ 才稳定支持;旧版浏览器(如 Chrome
为什么 postcss-preset-env 不能“全自动”处理 Nesting
很多人以为装了 postcss-preset-env 就万事大吉,但实际它对 Nesting 的处理有硬性前提:
- 必须显式启用
nesting-rules: true,默认是false - 只转换标准语法:
&、&:hover、& > p等,不支持@media或@supports内部嵌套(那些会被跳过) - 如果源码里混用了
postcss-nested插件(非 preset-env 自带),两者可能冲突,导致嵌套被展开两次或漏处理 -
stage: 3不保证 Nesting 生效——Nesting 属于 stage 4 特性,必须单独声明features: { 'nesting-rules': true }
嵌套选择器中 & 的行为差异必须手动校验
& 在原生 Nesting 中严格绑定父选择器作用域;而 PostCSS 展开后,等价于字符串拼接,容易因空格、换行或注释引入意外空格,导致生成错误选择器:
article {
color: #333;
& p { margin: 0; } /* ✅ 正确:article p */
&p { font-weight: bold; } /* ❌ 原生支持:articlep;PostCSS 展开后也是 articlep(无空格),但语义错误 */
}
- 避免紧贴
&写标签名(如&p),一律加空格或分隔符 - 不要在
&后直接跟伪类且无空格:&:hover安全,&:hover:hover可能展开为article:hover:hover(合法),但&:hover .btn必须确保中间有空格 - 嵌套中的属性名(如
color)不会被转译,但自定义属性(--foo)若在嵌套块内声明,需确认目标浏览器是否支持 CSS 变量(否则要配custom-properties一起 polyfill)
IE11 和老 Safari 下的展开结果必须手写 fallback
PostCSS 能把 article { p { color: red; } } 转成 article p { color: red; },但这只是语法转换——它不解决底层兼容问题:
- IE11 不支持
display: contents,如果你在嵌套中用了它,PostCSS 不会降级,得自己补display: block或用 JS 检测替换 - 老 Safari(≤16.3)解析
article p没问题,但若嵌套中用了:has()(哪怕在外层),整个规则块会被整条丢弃(:has不支持导致父规则失效) - 所有转换后的选择器长度受 IE11 的 4095 条 CSS 规则限制影响——嵌套越深,展开后规则数指数增长,极易超限,建议用
postcss-sorting合并重复声明
最易被忽略的一点:Nesting 本身不触发重排,但 PostCSS 展开后生成大量长选择器,可能拖慢老浏览器的样式计算;上线前务必用真实设备跑一次 Lighthouse 的 “Avoid large, complex selectors” 审计项。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











