@import加媒体查询并非按需加载,而是加载后按条件启用;真正按需(不发请求)须用<link>的media属性,且@import语法、位置、路径等限制严格,优先推荐<link>。

@import加媒体查询根本不是“按需加载”
它只是“加载后按条件启用”,浏览器仍会发起请求,哪怕当前不匹配媒体条件。你看到的“只在手机加载 mobile.css”,其实是假象——文件照样被下载,只是样式规则被忽略。真正按需(即不发请求)必须用 <link rel="stylesheet"> 的 media 属性。
@import媒体查询语法必须紧贴url,且不能换行
写错位置就完全失效,而且是静默忽略,连控制台警告都没有。
-
@import url("mobile.css") screen and (max-width: 768px);✅ 正确:媒体条件紧跟url()后、分号前 -
@import url("mobile.css"); screen and (max-width: 768px);❌ 错误:分号后的内容被当普通 CSS 解析,screen and (max-width: 768px)不是有效声明 -
@import url("mobile.css")\n screen and (max-width: 768px);❌ 错误:换行导致语法解析失败(部分浏览器直接跳过整条 @import) - 括号前后不能有空格:
@import url("dark.css") (prefers-color-scheme: dark);✅;( prefers-color-scheme: dark )❌
@import必须在CSS文件最顶部,前面只能有@charset
哪怕一行注释、一个空行、或一个 @layer 声明,都会让整条 @import 被浏览器无视——你改了文件却没生效,大概率栽在这儿。
- ✅ 正确顺序:
@charset "UTF-8";→@import url("base.css") screen;→ 其他规则 - ❌ 错误示例:顶部先有
/* reset */或body { margin: 0 },后面所有@import全部失效 - 内联
<style>中也一样严格:必须是<style>标签内的第一行内容 - 路径基于当前 CSS 文件位置,不是 HTML 页面位置——
main.css在/css/main.css,想引入同级print.css,就得写@import url("print.css");,不是../css/print.css
真正需要条件加载时,优先用<link>而非@import
@import 是同步阻塞的,多个串行加载会拉长 LCP,移动端尤其明显;而 <link> 可并行下载、支持 preload、能用 onload 控制启用时机。
立即学习“前端免费学习笔记(深入)”;
-
<link rel="stylesheet" href="mobile.css" media="screen and (max-width: 768px)">—— 浏览器原生判断,不匹配就不发请求 -
<link rel="stylesheet" href="text-styles.css" media="print" onload="this.media='all'">—— 加载完再启用,实现“加载后按需激活” - 旧版 iOS Safari 对
@import+(orientation: landscape)支持不稳定,<link>更可靠 - 构建工具(Vite/Webpack)通常不解析 CSS 中的
@import,除非额外配postcss-import,否则打包时直接丢弃
只有两种情况绕不开 @import 媒体查询:维护纯 CSS 遗留系统(无法改 HTML),或组件库需复用同一份 CSS 文件但通过不同入口注入媒体逻辑(如用 @import ... (prefers-color-scheme: dark) 切换主题)。其他时候,<link> 是更可控、更可调试的选择。


















