最常见三个原因是:未加viewport标签导致移动端不触发、媒体类型错误(如print在浏览器中无效)、min-width与max-width逻辑颠倒。

直接用 @media 写断点就行,但关键不是“能不能写”,而是“写在哪、怎么断、为什么断错”。很多人加了 @media 没反应,不是语法错,是漏了 viewport 或媒体类型没对上。
为什么写了 @media 但样式完全不生效
最常见三个原因:
• 页面没加 <meta name="viewport" content="width=device-width, initial-scale=1">,移动端强制以桌面宽度渲染,max-width: 768px 永远不触发
• 写了 @media print { ... } 却在浏览器里看效果,自然没变化
• 把 min-width 和 max-width 搞反,比如想“小屏用浅色”,却写了 @media (min-width: 768px) { body { background: lightgray; } } —— 这其实是大屏才生效
- 检查控制台 Elements 面板里,对应样式是否被划掉(表示未匹配)
- 用 Chrome DevTools 的 “Toggle device toolbar” 切换 iPhone SE / iPad / Desktop,别只靠缩浏览器窗口
- 如果用外链 CSS,确认
<link>标签里没误写media="screen"又在内部再套@media screen,造成双重限定
移动端优先还是桌面优先?别被说法带偏
真正影响结果的不是口号,是断点逻辑顺序。CSS 是从上到下解析,后写的规则会覆盖前面同权重的规则。所以:
- 移动优先:默认写基础样式(小屏),再用
@media (min-width: 769px)往上加适配 —— 推荐,代码更少,语义清晰 - 桌面优先:默认写桌面样式,再用
@media (max-width: 768px)往下收窄 —— 容易漏改,维护成本高 - 别混用:同一组件里不要既有
min-width又有max-width断点,容易重叠或留空隙,比如(max-width: 768px)和(min-width: 769px)中间没覆盖 768.5px 这种非整数宽度(虽然实际极少,但逻辑不干净)
除了 width,这些媒体特性真有用
width 是入门,但真实项目常要更细粒度控制:
立即学习“前端免费学习笔记(深入)”;
-
orientation: portrait:竖屏时隐藏横屏才需要的工具栏,比如视频页全屏按钮 -
prefers-color-scheme: dark:配合系统深色模式自动切主题,不用 JS 监听,性能好且可服务端预判 -
hover: hover:判断设备是否支持悬停(比如带触控笔的 Windows 平板),避免给触摸设备显示 hover 提示 -
resolution: 2dppx:针对 Retina 屏替换高清图标,background-image: url(icon@2x.png)只在高 DPI 下加载
注意:prefers-reduced-motion 这类特性虽小众,但加一行 @media (prefers-reduced-motion: reduce) { * { animation-duration: 0.01ms !important; } } 就能过 WCAG 可访问性审计,很多团队直接忽略。
@media 嵌套和性能隐患
CSS 本身不支持嵌套 @media,但像 Sass 这类预处理器允许写:
@media (min-width: 768px) {
.card {
@media (hover: hover) {
&:hover { transform: translateY(-2px); }
}
}
}编译后会生成两层独立 @media,没问题。但要注意:
- 单个 CSS 文件里别堆超过 20 个
@media块,尤其每个都含大量选择器 —— 浏览器需反复计算匹配,低端安卓机可能卡顿 - 避免在
@media里重复定义全局字体、颜色变量,应抽成 :root 自定义属性,媒体查询只改变量值 - 用
only screen而非screen开头,能过滤老 IE 对@media的错误解析(虽然现在基本不用兼容 IE,但遗留项目仍存在)
最常被跳过的细节:媒体查询里的单位必须是视口单位(px、em、rem),不能用 cm、in 这类物理单位做断点 —— 它们在不同设备上换算结果不可控,iOS Safari 甚至会直接忽略整条规则。


















