link标签的media属性支持完整的CSS媒体查询语法,如(max-width: 768px)、(prefers-color-scheme: dark)、(hover: hover)等;它在HTML解析阶段决定是否下载CSS文件,匹配才请求,不匹配则静默跳过,实现真正按需加载。

link标签的media属性支持哪些媒体查询语法
它支持完整的 CSS 媒体查询语法,不是只认 screen 或 print 这类简单关键字。只要浏览器能解析的媒体查询条件,media 都能用,比如 (min-width: 768px)、(prefers-color-scheme: dark)、(hover: hover)。
但注意:浏览器**只在匹配时才下载并应用该 CSS 文件**,不匹配则跳过加载——这是关键优化点,不是“先加载再判断”。
-
media值为空或非法(如media="not screen")时,多数浏览器会忽略该<link>,不发起请求 - 写成
media="all"等价于不写media属性,始终加载 - 多个条件用
and连接,or要写成逗号分隔(如(min-width: 480px), (orientation: landscape))
如何避免移动端重复加载桌面样式
常见错误是把桌面和移动样式都写进同一个 CSS 文件,再靠媒体查询内部规则控制显示,这会导致所有设备都下载完整 CSS。用 media 属性拆分才是真按需加载。
例如:
立即学习“前端免费学习笔记(深入)”;
<link rel="stylesheet" href="mobile.css" media="(max-width: 767px)"> <link rel="stylesheet" href="desktop.css" media="(min-width: 768px)">
这样手机只请求 mobile.css,桌面只请求 desktop.css,网络和解析开销都降下来了。
- 务必确保两个文件里没有重复规则,否则维护成本飙升
- 不要依赖
@import在 CSS 内部做媒体查询拆分——它不触发按需加载,主文件仍全量下载 - 如果用构建工具(如 Webpack),注意 loader 是否保留
media属性;有些压缩插件会误删空media或非法值
prefers-color-scheme 和 print 场景的实际写法
这两个是当前最实用的场景:prefers-color-scheme 实现暗色模式自动切换,print 控制打印样式——它们都依赖 media 属性精准触发。
示例:
<link rel="stylesheet" href="light.css" media="(prefers-color-scheme: light)"> <link rel="stylesheet" href="dark.css" media="(prefers-color-scheme: dark)"> <link rel="stylesheet" href="print.css" media="print">
注意:prefers-color-scheme 在 Safari 12.1+、Chrome 76+、Firefox 93+ 才支持;旧浏览器会忽略对应 <link>,所以必须提供默认样式(比如不带 media 的基础 CSS)。
-
print样式表里的@media print { ... }是冗余的,外部media="print"已足够 - 测试暗色模式时别只靠系统设置——用浏览器 DevTools 的 Rendering 面板强制切换,比重启更可靠
- 某些 CMS 或静态站点生成器会把
<link>写进<body>,这不符合规范,可能导致 FOUC 或加载异常
为什么有时候 media 匹配了但样式没生效
最常被忽略的是层叠顺序问题:多个 <link> 按 HTML 中出现顺序加载,后加载的 CSS 规则优先级更高。如果 mobile.css 在 desktop.css 后面,即使屏幕宽度 desktop.css 里的规则仍可能覆盖 mobile.css 里的同名选择器。
- 检查 Network 面板确认对应 CSS 文件是否真的被请求——没发请求说明
media不匹配或语法错 - 用 DevTools 的 Styles 面板看某元素最终生效的样式来自哪个文件,再反查
<link>加载顺序 -
media值大小写敏感:screen可以,SCREEN就失效 - 响应式断点单位要用
px,别混用em或rem——media查询只支持绝对长度单位
真正麻烦的不是写法,而是当页面有 JS 动态插入 <link>、或 SSR 渲染时服务端预判 media 不准确,这时候客户端实际环境和预加载逻辑就容易对不上。



















