link的media属性支持完整CSS@media语法,包括screen、print、(min-width:768px)、(prefers-color-scheme:dark)等,但必须语法严格(括号闭合、空格规范、带screen and前缀),否则降级为media="all"强制下载。

link 的 media 属性到底支持哪些值
它不是只能填 screen 或 print,而是完整支持 CSS @media 规则的语法,包括括号、空格、逻辑操作符和媒体特性。但浏览器只在语法完全合法时才真正跳过请求——否则就当 media="all" 处理,照下不误。
-
screen and (min-width: 768px)是推荐写法;单独写(min-width: 768px)缺少媒体类型前缀,旧版 Safari、Electron 会忽略整条<link> -
print在 Chrome/Edge “另存为 PDF” 时触发,但 Safari 对@page支持不稳定,打印样式必须单独验证 -
(prefers-color-scheme: dark)和(prefers-reduced-motion: reduce)需注意兼容性:Safari 14+ 才支持后者,IE 完全不识别 -
not screen这类写法风险高——部分 WebView 直接忽略整条规则,不建议用
为什么写了 media="(max-width: 768px)" 桌面端还在下载 CSS
这不是 bug,是降级行为:浏览器解析失败后,自动 fallback 到 media="all",强制下载。常见原因包括:
- 括号不闭合、用了中文括号、冒号后没空格(如
min-width:768px)——浏览器不报错,但根本不匹配 -
media=""或属性值为空字符串,等价于未设 media,所有设备都加载 - IE9 及更早版本完全无视 media,Android 4.4 WebView 也有类似问题
- 断点之间有缝隙或重叠,比如
screen and (max-width: 767px)和screen and (min-width: 768px)之间没有767.5px这种情况,但若写成max-width: 767px和min-width: 768px,理论上已覆盖全部整数宽度
验证是否真跳过?唯一方式是打开 DevTools → Network → 刷新 → 筛选 css → 看那个文件是否根本没出现在列表里。出现了,就说明没跳过。
rel="preload" + media 才能真正控制是否发起请求
rel="stylesheet" 的 media 控制的是“是否应用”,而 rel="preload" 的 media 才控制“是否发起 HTTP 请求”。要确保非目标设备连预加载都不做,必须配对使用:
立即学习“前端免费学习笔记(深入)”;
<link rel="preload" as="style" href="dark-theme.css" media="(prefers-color-scheme: dark)"> <link rel="stylesheet" href="dark-theme.css" media="(prefers-color-scheme: dark)">
-
rel="preload"必须带as="style",否则浏览器无法识别资源类型,media会被忽略 - 不能只写
preload就完事——它不应用样式,后面仍需补一个rel="stylesheet" - 只对 JS 不会动态引入的资源用它,否则可能重复加载(比如用户手动切换深色模式后再触发 preload)
media 是静态声明,不随窗口缩放自动切换
HTML 中 <link> 的 media 值只在页面加载时判断一次,不会响应 resize 事件。想实现动态切换(比如拖动浏览器窗口时实时换 CSS),得靠 JS:
- 监听
window.matchMedia(),例如window.matchMedia("(prefers-color-scheme: dark)").matches - 修改已存在的
<link>元素的disabled属性,或动态插入/移除节点 - 注意:修改
<style media="..."></style>的media属性不会触发重载,它在解析完成后就固定了
最易被忽略的一点:media 属性的语法容错极低——一个空格错位,就等于白写;而验证又必须看 Network 面板,不能只靠视觉效果或 console.log 判断是否生效。



















