media 属性决定浏览器是否发起 HTTP 请求,不匹配时通常不下载 CSS;但写错、写漏或用错场景会导致白加载、重复加载或样式失效。

media 属性不是“开关”,它决定浏览器是否发起 HTTP 请求——不匹配时,大多数情况下根本不会下载 CSS 文件;但一旦写错、写漏或用错场景,就容易白加载、重复加载,甚至样式失效。
media 不匹配时到底下不下文件?
取决于 media 值是否被浏览器识别为“当前环境不匹配且可跳过”。比如:
-
media="screen and (max-width: 480px)"在桌面宽屏下,Chrome/Firefox/Safari 都不会发请求(Network 面板里看不到) -
media="print"在普通浏览时,现代浏览器也不下载——但注意:部分旧版 Edge 或 WebView 可能预加载,行为不一致 -
media="not screen"或media="handheld"这类废弃/模糊值,浏览器通常退化为media="all",导致误加载 -
media="(min-width: 768px)"漏掉括号写成media="min-width: 768px",会被当成无效值,等同于media="all"
多个 media link 同时生效会冲突吗?
会,而且冲突方式很隐蔽:不是样式覆盖问题,而是加载时机和层叠顺序问题。
- 两个
<link>同时满足条件(比如tablet.css和desktop.css都匹配当前宽度),它们都会下载、解析,并按 HTML 中的书写顺序参与 CSSOM 构建 - 如果
desktop.css里重写了tablet.css的按钮颜色,但写在前面,那实际生效的是后面那个——顺序比 media 条件优先级高 - 旋转手机瞬间(portrait ↔ landscape),
media="(orientation: portrait)"和media="(orientation: landscape)"可能短暂共存,造成样式抖动 - 真正隔离多套样式,推荐单个 CSS 文件内用
@media规则,而不是拆成多个<link>
想让 dark-mode.css 只在深色模式下加载,怎么写?
直接写 <link rel="stylesheet" href="dark-mode.css" media="(prefers-color-scheme: dark)"> 即可,但要注意三点:
立即学习“前端免费学习笔记(深入)”;
- 该
<link>必须在 HTML 中静态存在(不能 JS 动态插入),否则系统切换主题时浏览器不会自动加载/卸载 - Safari 14+ 才支持
prefers-color-scheme的自动响应,旧版 Safari 需 fallback 到 JS 检测window.matchMedia - 不要同时写
light-theme.css和dark-theme.css两个medialink——用户从浅色切深色时,浅色样式不会自动 disabled,得手动操作link.disabled = true
怎么用 media 实现非阻塞异步加载?
最稳妥的做法是:<link rel="stylesheet" href="async.css" media="print" onload="this.media='all'">
- 利用
media="print"让浏览器认为“当前不需渲染”,从而跳过同步阻塞,但依然触发下载 -
onload回调必须立即执行this.media = 'all',否则样式永远不会生效 - 务必加
this.onload = null,否则缓存复用或脚本重入时可能重复触发 - 别用
media="none"—— Firefox 旧版本不触发onload,兼容性差 - 这个技巧对首屏关键样式不适用,只适合非核心 CSS(如动画、字体图标、主题扩展)
真正容易被忽略的点是:media 是 HTML 解析阶段就起作用的静态判断,它不感知 JS 状态、localStorage、UA 字符串,也不响应 resize——所有运行时逻辑,都得靠 JS 动态插入 <link>,而不是指望 media 自己“聪明起来”。



















