浏览器只在media属性匹配当前环境时才发起CSS请求,这是真正按需加载的起点;media值必须带媒体类型前缀如“screen and (max-width: 767px)”,否则旧版Safari会忽略,且多条件须互斥以防重复下载。

浏览器只在 link 标签的 media 属性匹配当前环境时,才发起对应 CSS 的网络请求——这是真正按需加载的起点。别指望 @media 块能阻止文件下载,它只控制规则是否生效。
用 link media 实现初始条件加载
HTML 解析阶段就决定是否拉取资源,不匹配则根本不会发请求。关键在写法必须规范:
-
media值必须带媒体类型前缀,如screen and (max-width: 767px),不能只写(max-width: 767px),否则旧版 Safari 会忽略 - 多个
link的条件要互斥,比如screen and (max-width: 767px)和screen and (min-width: 768px)是安全的;但若漏掉and (orientation: portrait),横屏手机可能同时命中两个条件,导致双倍下载 - 路径推荐用根相对路径,如
/css/mobile.css,避免构建后因目录嵌套导致 404(静默失败,Network 面板里都看不到请求)
为什么 @import 和内联 @media 不算“按需加载”
@import 写在 CSS 文件里,或整个样式表里塞满 @media 规则,都无法阻止主 CSS 文件被完整下载和解析。浏览器必须先拿到、解析完主文件,才能执行里面的条件逻辑。
-
@import url("theme.css") (prefers-color-scheme: dark);看似按需,实则theme.css的请求仍依赖主 CSS 加载完成,延迟明显 - 所有
@media规则都会参与 CSSOM 构建,哪怕当前不匹配,低端 Android WebView 中可能拖慢首屏渲染 - 开发者工具 Network 面板里查不到被
link media屏蔽的请求,但能看到@import或内联@media对应的全部 CSS 请求
动态切换时不要直接改 link.media
修改 link.media 属性本身不会触发重新加载,浏览器只在元素插入 DOM 时检查一次。常见错误是监听 resize 后直接赋值,结果样式没变。
立即学习“前端免费学习笔记(深入)”;
- 正确做法是移除再重插节点:
link.remove(); document.head.appendChild(link); - 如果要用
disabled控制,得先设link.disabled = false,再改media,否则 Safari 可能缓存旧状态 - 慎用
matchMedia监听(hover: hover),部分安卓 WebView 不识别,会退化为无条件加载
最易被忽略的一点:构建工具打包时,link 标签必须保持独立存在,不能被 HTML 压缩器合并或移除空格——某些工具会把 media 属性误判为无效而删掉。


















