<link media> 不阻断 CSS 下载,仅控制样式是否生效;真正条件加载需用 JS 动态插入、服务端响应或单文件 @media 方案。

media 属性本身不实现媒体查询逻辑,它只是让浏览器「有条件地加载」外部 CSS 文件——但所有带 media 的 CSS 文件仍会被下载(除非是 print 等非屏幕类型且未激活),样式是否生效才取决于内部的 @media 规则。
用 <link media="..."> 加载 CSS 时,文件仍会下载
很多人以为写成:<link rel="stylesheet" media="screen and (max-width: 768px)" href="mobile.css">
就能只在小屏时下载 mobile.css。事实是:现代浏览器(Chrome/Firefox/Safari)会预加载所有 rel="stylesheet" 的资源,media 值只控制「是否将该 CSS 应用于渲染」,不阻断下载。
- 这意味着:即使你用
media="print",文件照样被拉下来,只是不参与屏幕样式计算 - 移动端首次加载时,
desktop.css和mobile.css可能同时发请求,浪费带宽 - 若两个文件里有同名选择器,后加载的 CSS 优先级更高,容易覆盖预期样式
media 属性和 @media 规则不是一回事
<link media="..."> 的值必须是「媒体类型 + 媒体特性」的合法组合,比如:screen、print、screen and (min-width: 769px);但它不能包含 CSS 声明。真正做样式适配的,还是文件内部的 @media 块。
- 错误写法:
<link media="(max-width: 768px)" href="style.css">—— 缺少媒体类型,部分旧版 Safari/Electron 会忽略整条 link - 正确写法:
<link media="screen and (max-width: 768px)" href="style.css"> - 更稳妥写法:
<link media="screen" href="style.css">,然后把断点逻辑全放在style.css里的@media screen and (max-width: 768px)中
想真正按条件加载?得换方案
如果目标是「小屏只加载小屏 CSS,大屏跳过」,<link media> 不够用,需配合其他机制:
立即学习“前端免费学习笔记(深入)”;
- 用
<link rel="preload">预加载关键 CSS,再用 JS 检测window.matchMedia()动态插入<link rel="stylesheet"> - 服务端根据 UA 或客户端提示(如
Sec-CH-UA-Mobile)返回不同 HTML,控制<link>是否存在 - 构建时拆包 +
import条件加载(如 Webpack 的import(/* webpackMode: "lazy" */ "./mobile.css")) - 放弃分文件,统一用单个 CSS + 移动端优先的
@media (min-width: ...),这是最轻量、最可控的做法
真正容易被忽略的是:你以为删掉一个 <link media> 就省了请求,其实没省;而把所有断点塞进一个文件,反而更容易控制层叠顺序、避免重复下载、也方便用 clamp() 或 CSS 变量替代部分 @media。



















