media query 仅控制样式生效,不引入css文件;按条件加载需用或js动态插入。常见失效原因包括缺失viewport meta、断点不匹配视口、选择器权重覆盖、@import阻塞及media属性兼容性问题。

Media Query 本身不能“引入”CSS 文件,它只控制已有样式是否生效;真要按条件加载不同 CSS,得用 <link media> 或 JS 动态插入 —— 这是多数人卡住的第一步。
为什么写了 @media (max-width: 768px) 却没生效
常见现象:CSS 文件里写了小屏规则,但手机上完全没变。这不是 Media Query 失效,而是它根本没被触发或被覆盖。
-
<meta name="viewport" content="width=device-width, initial-scale=1">缺失 —— 没它,移动端浏览器会以约 980px 渲染,max-width: 768px永远不匹配 - 断点值和实际视口对不上:iPhone 14 竖屏视口是 390px,写
max-width: 480px没问题,但若写成max-width: 320px就漏掉了 - 选择器权重太高:比如全局写了
.header nav a { color: blue },小屏里只写a { color: red },后者会被前者覆盖 -
@media规则写在了@import后面,而@import阻塞解析,导致后续规则未被读取
用 <link media> 实现真正按需加载
这是最轻量、无需 JS、浏览器原生支持的方案:匹配时才发起网络请求,不匹配就完全不下载。
- 多个
<link>的media必须互斥,否则可能同时加载两个文件:mobile.css和desktop.css不能都用min-width,推荐一个用max-width: 767px,另一个用min-width: 768px - 路径必须准确:
href="css/mobile.css"写成href="mobile.css"而实际文件在子目录下,就会静默失败(Network 面板里看不到请求) - IE9 及以下会忽略
media属性,无条件加载所有 CSS;如需兼容,得 fallback 到 JS 检测 +document.write或动态插入 - 不要混用
screen and (max-width: 768px)和(max-width: 768px)—— 前者明确限定媒体类型,后者依赖默认all,部分旧 WebView 行为不一致
JS 动态插入 <link> 的关键细节
适合运行时判断场景(如用户手动切换主题、localStorage 记录偏好),但容易踩坑。
-
window.matchMedia()是首选检测方式,比 UA 字符串或screen.width更可靠,且支持监听变化 - CSS
<link>的onload事件在 Firefox 和旧 Safari 中根本不触发 —— 正确做法是轮询link.sheet && link.sheet.cssRules.length > 0,最多重试 5 次 - 插入后记得加
id,比如link.id = "dark-theme",方便后续document.getElementById("dark-theme")?.remove() - 避免在 DOMContentLoaded 之前插入大量
<link>,否则可能阻塞首屏渲染;可结合requestIdleCallback延迟非关键样式加载
最容易被忽略的是:断点数值不是凭经验写的,而是由你项目中真实内容溢出的位置决定的;@media 是开关,<link media> 才是闸门——前者管“用不用”,后者管“下不下载”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











