媒体查询嵌套必须用&显式引用父选择器,否则子选择器会脱离上下文生成全局规则;正确写法为.card { @media (min-width: 768px) { & .title { font-size: 1.5rem; } } },编译为.card .title。

媒体查询嵌套必须用 & 引用父选择器
原生 CSS 嵌套中,@media 不能单独存在,它必须嵌在某个选择器内部,且内部规则需显式使用 & 表示父级上下文。否则编译结果会出错或语义断裂。
常见错误是直接写:.card { @media (min-width: 768px) { .title { font-size: 1.5rem; } } }
这会导致 .title 脱离 .card 上下文,实际匹配的是全局所有 .title,而非 .card .title。
- 正确写法必须带
&:.card { @media (min-width: 768px) { & .title { font-size: 1.5rem; } } } -
& .title编译为.card .title(后代);&.title编译为.card.title(同元素多类) - 不写
&的子选择器(如.title)会被视为“新独立规则”,等价于把样式提到了顶层,破坏封装性
避免在嵌套媒体查询里复刻 DOM 结构
有人习惯按 HTML 层级写嵌套:.container { .main { .section { @media (min-width: 1024px) { ... } } } }。这看似清晰,实则埋下三重隐患:
- 选择器深度超 3 层,浏览器匹配效率下降(从右往左查
...时要回溯多次) - 一旦某层 HTML 结构微调(比如
.section换成.content),整块样式失效 - 媒体查询本应表达“响应行为”,不是“结构快照”——真正该响应的往往是组件自身状态,而非祖先标签是否还存在
更稳妥的做法是:媒体查询紧贴最外层组件类,只嵌一层子级,例如:.card { @media (min-width: 768px) { & .header { display: flex; } & .body { grid-column: span 2; } } }
慎用嵌套媒体查询 + 伪类组合
像 &:hover 和 @media 同时嵌套是合法的,但容易写出不可预测的行为。例如:
.btn { @media (hover: hover) { &:hover { background: #007bff; } } }
这段代码本意是“仅在支持悬停的设备上启用 hover 效果”,但它有两个隐藏问题:
-
@media (hover: hover)是功能媒体查询,不是尺寸型,部分旧版 Safari 对它的解析不稳定 - 如果外部已有
.btn:hover规则,而这个嵌套版本又没覆盖全部属性,会出现层叠冲突 - 更严重的是:嵌套后,
&:hover实际生成的选择器是.btn:hover,和非嵌套写法无异,但可读性反而下降
建议拆开写:媒体查询控制布局/尺寸,伪类控制交互态,两者分层处理。需要条件化交互时,优先用 @supports 检测能力,而非嵌套媒体查询。
嵌套媒体查询不解决资源加载问题
有人误以为在 CSS 中嵌套 @media 能让浏览器“只下载对应断点的样式”。这是误解。所有嵌套的媒体查询规则仍会随主 CSS 文件一起下载、解析,只是匹配失败时不生效。
真正节省资源的方式仍是外部文件 + <link media="...">,例如:<link rel="stylesheet" href="desktop.css" media="screen and (min-width: 1024px)">
嵌套媒体查询的价值在于逻辑聚拢——把“卡片在桌面端怎么排,同时标题字号怎么变”这些强关联规则写在一起,而不是散落在不同文件或相隔几十行的 CSS 中。它优化的是人对样式的理解成本,不是网络请求量。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











