原生 CSS 嵌套允许将 @media 写入选择器内部(如 .card { @media (min-width:768px) { & .title { ... } } }),自动继承父选择器、减少重复类名,但 @media 条件中不支持 var() 或运行时计算,且必须嵌套在已声明的选择器内才生效。

原生 CSS 嵌套(CSS Nesting)本身不能简化 @media 的条件书写,但它能显著减少媒体查询块的重复声明和选择器冗余——关键在于「把 @media 写进组件内部」,而不是在全局反复写 .card、.header 等前缀。
媒体查询必须嵌套在选择器内部才生效
原生嵌套不支持顶层 @media 块里再写嵌套规则(比如 @media (min-width: 768px) { .card { ... } } 里面用 & .title),但允许你把 @media 放到某个选择器作用域内,此时 & 能正确解析为该父选择器:
-
@media必须出现在一个已声明的选择器块内部,否则会被浏览器忽略(Chrome/Firefox/Safari 均如此) - 嵌套的
@media中所有子规则自动继承父选择器上下文,无需重复写类名 - 错误写法:
@media (min-width: 768px) { & .title { color: red; } }——&在顶层无意义,会报解析错误 - 正确写法:
.card { @media (min-width: 768px) { & .title { color: red; } } }
嵌套媒体查询 vs 传统写法:真实体积对比
假设你要为 .card 组件定义三套断点下的标题样式,传统写法需三次重复类名;嵌套后只需一次声明 + 三层 @media 块:
.card {
padding: 1rem;
& .title {
font-size: 1rem;
}
@media (min-width: 768px) {
& .title {
font-size: 1.25rem;
}
}
@media (min-width: 1024px) {
& .title {
font-size: 1.5rem;
}
}
}
- 优势:HTML 结构不变,CSS 文件更紧凑,修改
.card类名时只需改一处 - 注意:每个
@media块内仍需用&显式引用父级,不能省略(.title单独写会变成全局选择器) - 不推荐深度嵌套媒体查询,如
& .title { @media (...) { &::before { ... } } }—— 浏览器兼容性差,且可读性骤降
与 CSS 变量配合时的常见失效点
很多人想用 --breakpoint-md 替代硬编码像素值,但 @media (min-width: var(--breakpoint-md)) 是非法语法,浏览器直接跳过整块。嵌套无法绕过这个限制:
立即学习“前端免费学习笔记(深入)”;
-
@media条件部分永远不接受var()、calc()或任何运行时计算 - 变量只能用在
@media块「内部」的声明中,例如font-size: var(--fs-title) - 若要集中管理断点,只能靠构建工具(如 PostCSS 插件)做预处理,或手动维护一组常量注释
- 容易踩的坑:在嵌套的
@media块里给:root设变量(:root { --x: 1 }),这不会触发重计算,对应元素也不会更新
真正省事的地方在于组织逻辑:一个组件的所有响应式变体,现在可以收拢在同一个 { } 块里,而不是散落在 CSS 文件不同位置。但别指望它能帮你少写几个像素值——那仍是媒体查询自身的语法边界。


















