原生CSS @nest 语法已在Chrome 119+、Safari 17.2+、Firefox 125+稳定支持,但SCSS不兼容该语法,误写会报错;SCSS需用&实现扁平嵌套,避免空格导致后代选择器膨胀,并严格控制层级不超过3层。

原生 CSS 的 @nest 语法(CSS Nesting Module Level 3)已在 Chrome 119+、Safari 17.2+、Firefox 125+ 中稳定支持,但 SCSS 本身**不兼容也不转换**该语法——你不能在 .scss 文件里直接写 @nest & > li { ... } 并指望它被编译或运行;SCSS 解析器会报错或静默忽略。要实现“类似原生嵌套的扁平写法”,必须回归 SCSS 自身的嵌套机制,并主动规避其易错点。
SCSS 嵌套不是原生 @nest,别混用
原生 @nest 是浏览器运行时解析的,允许任意嵌套层级、动态选择器组合(如 @nest .item & + .item),而 SCSS 嵌套是编译期静态拼接,依赖 & 引用父选择器。两者语义和能力完全不同:
-
@nest可以脱离上下文独立存在;SCSS 嵌套块必须挂载在某个父选择器下(如.card { ... }) - 写
.card { @nest & > h2 { ... } }在 SCSS 中非法,@nest不是 SCSS 关键字 - 若你在
.scss文件中误用了@nest,Sass 编译器(dart-sass)会直接报错:Invalid CSS after "@nest": expected "{", was "& > h2 {"
用 & 实现真正扁平、可读的嵌套结构
SCSS 扁平写法的核心是:用 & 显式声明关系,避免隐式子选择器歧义,同时控制缩进层级。常见错误是把嵌套当缩进格式用,结果生成冗余选择器。
- ✅ 正确扁平写法:
.card { &__title { margin: 0; } &__body { padding: 1rem; } }→ 输出.card__title{...}.card__body{...} - ❌ 错误缩进写法:
.card { __title { ... } }→ 输出.card __title{...}(空格是后代选择器,非 BEM) - 兄弟/子元素关系必须显式带符号:
.list { & > li { display: block; } & + .list { margin-top: 1em; } },&和>之间不能换行或加空格 - 避免三层以上嵌套:
.modal { .header { .title { ... } } }会生成.modal .header .title,特异性高且难覆盖;应改用.modal-header-title或拆为独立选择器
想兼容原生嵌套?得切到 .css 文件 + 启用 @nest
如果你真需要原生嵌套行为(比如动态计算选择器、与 JS 运行时样式联动),就不要用 SCSS 编译流程。直接写 .css 文件,并启用现代浏览器支持:
立即学习“前端免费学习笔记(深入)”;
- 确保构建工具(如 Vite、Webpack)不把
.css当作 SCSS 处理;禁用sass-loader或style-resources-loader对该文件的介入 - 写法示例:
.article { @nest & > h2 { font-size: 1.5rem; } @nest &:has(> blockquote) { border-left: 4px solid #3b82f6; } } - 注意兼容性兜底:原生
@nest在旧版 Edge、iOS Safari @supports (selector(:is(*))) 或降级为 SCSS 编译版本双轨维护
最常被忽略的一点:SCSS 的“扁平”是视觉缩进上的扁平,不是逻辑上的扁平——只要用了嵌套块,它就在编译时固化了选择器层级。真正解耦样式逻辑,得靠 @mixin + var(--x) 组合,而不是追求嵌套多浅。


















