CSS变量不能在@media中使用,因媒体查询需解析常量而变量为运行时计算,所有主流浏览器均静默忽略;可行方案是@custom-media或预处理器代入。

不能直接在 @media 里用 var(--breakpoint-md),这是个常见误解。浏览器目前(截至2026年4月)不支持在媒体查询条件中解析 CSS 变量,写了也无效,样式不会生效。
为什么 var() 在 @media 中不工作
CSS 变量是运行时计算的,而媒体查询的解析发生在样式计算早期,此时变量值尚未注入。你写 @media (min-width: var(--breakpoint-md)),浏览器会直接忽略整条规则,DevTools 里甚至看不到它被解析——不是报错,是静默失效。
- 所有主流浏览器(Chrome、Firefox、Safari、Edge)都如此,没有例外
- 哪怕你在
:root正确声明了--breakpoint-md: 768px,也无济于事 - 这不是语法错误,是 CSS 规范层面的限制:媒体查询条件必须是“已知常量”
真正能用 CSS 变量管理断点的两种方式
想统一维护断点又不依赖构建工具?只有两个现实路径:
-
用
@custom-media:Safari 原生支持,Chrome/Firefox 需 PostCSS 插件(如postcss-custom-media)转译。写法干净:@custom-media --md-up (min-width: 768px);,然后@media (--md-up) { ... } -
预处理器代入:Sass/Less 中定义
$breakpoint-md: 768px,再在@media (min-width: $breakpoint-md)中使用。变量在编译期展开,生成的是纯 CSS
别信“加个 !important 就行”或“换单位就能绕过”的说法——rem/em 同样不被支持。
立即学习“前端免费学习笔记(深入)”;
如果坚持用纯 CSS + :root 变量,只能这样妥协
把断点值挪到属性里,靠 JS 或伪元素间接驱动逻辑:
- 在
:root设--breakpoint-md: 768(纯数字,无单位) - 用伪元素
::before的content输出该值,再用 JS 读取:getComputedStyle(document.documentElement).getPropertyValue('--breakpoint-md') - 配合
window.matchMedia()手动比对,实现 JS 层面的断点响应
这适合需要 JS 动态行为的场景(比如懒加载、动画开关),但无法替代 CSS 媒体查询本身——样式层仍得另写一遍 @media (min-width: 768px)。
最易被忽略的一点:很多人把断点变量和布局变量混在同一个 :root 区块里,结果改一个 --spacing-lg 顺手调了 --breakpoint-lg,却没意识到前者影响视觉节奏,后者决定布局结构,演化逻辑完全不同。断点变量建议单独成块,加注释隔开,命名带 --breakpoint- 前缀,一眼可辨。


















