@media (orientation: landscape) 在桌面端完全不触发,真机也常因权限或初始状态失效;更可靠的是用 @media (min-width: 768px) and (max-height: 400px) 等宽高组合条件,并为横竖屏各自完整重写 grid-template 值。

直接说结论:用 @media (orientation: landscape) 做横竖屏切换在桌面端根本不会触发,真机上也常因权限或初始状态失效;更可靠的做法是用 @media (min-width: 768px) and (max-height: 400px) 这类宽高组合条件,配合完整重写 grid-template 值。
为什么 @media (orientation: landscape) 经常不生效
这个媒体查询只对真实移动端设备(且已授方向权限)有效,桌面浏览器 resize 时完全无视它。iOS Safari 需手动允许方向传感器,安卓 WebView 在锁屏旋转下也不更新。更隐蔽的问题是:即使匹配了,浏览器也不会“合并”新旧 grid-template,而是全量覆盖——漏写任何一部分,整个网格就退回到默认的 none 状态。
常见错误现象:
- 横屏后布局塌成单列,检查发现只改了
grid-template-columns,但没重写grid-template-areas - 真机调试时第一次加载是竖屏,转横屏后样式没变,等半秒才跳——这是重排延迟,不是代码错
- 桌面模拟器里怎么旋转都不触发,因为 orientation 不被 desktop Chrome/Firefox 支持
横竖屏必须各自定义完整的 grid-template
grid-template 是简写属性,浏览器不保留旧值。你不能指望“竖屏设好模板,横屏只调列宽”,它会直接丢弃所有区域定义。
正确做法是:
- 竖屏完整写:
grid-template: "header header" "nav main" "footer footer" / 1fr 3fr; - 横屏也必须完整写:
grid-template: "header nav footer" "header main footer" / 1fr 2fr 1fr; - Firefox 对换行敏感,
grid-template值必须写在单行内,否则解析失败 - 如果用
grid-template-areas+grid-template-columns分开写,横竖屏都得同步更新两处,容易漏
用宽高组合代替 orientation 更稳定
实际项目中,@media (min-width: 768px) and (max-height: 400px) 比单纯 orientation 可靠得多。它不依赖传感器,只看视口尺寸,桌面拖拽窗口也能响应。
常用断点参考:
- 横屏倾向:
@media (min-width: 600px) and (max-height: 400px)(适合手机横置、小平板) - 竖屏倾向:
@media (max-width: 480px), (min-height: 600px)(覆盖窄屏+高屏场景) - 避免用
device-width,高 DPR 设备上它返回 CSS 像素,不是物理宽度 - 可叠加
aspect-ratio做双保险(@media (aspect-ratio: 16/9)),但注意 Safari 15.4+ 才支持
别忘了 <meta name="viewport"> 这个前提
没有正确的 viewport 标签,所有媒体查询都白搭。必须确保 HTML 中有:
<meta name="viewport" content="width=device-width, initial-scale=1.0">
缺了 width=device-width,iOS Safari 会按竖屏宽度渲染横屏页面,orientation: landscape 永远不匹配。另外,user-scalable=no 虽非必需,但在某些安卓 WebView 中能防止缩放干扰方向判断。
最易被忽略的一点:横竖屏切换时,grid-template-areas 中的字符串顺序要跟着主轴方向重排——比如竖屏时 “a b c” 是从上到下三行,横屏时就得改成 “a b c” 从左到右三列,否则区域映射会错位。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











