viewport标签错误会导致orientation媒体查询失效,因iOS Safari和Android Chrome依赖其识别方向变化;需配对且含width=device-width,推荐使用100dvh、gap及matchMedia监听。

viewport 标签写错,@media (orientation: landscape) 就不会触发
横竖屏媒体查询失效,八成是 <meta name="viewport"> 没配对或被覆盖。iOS Safari 和 Android Chrome 都依赖它识别方向变化,缺了或写错,浏览器压根不重算 orientation 媒体查询。
常见错误包括:
- 漏掉
width=device-width—— 缺它,横屏时仍按竖屏逻辑渲染,orientation: landscape永远不匹配 - 用了固定值如
width=375—— 视口宽度锁死,方向切换后尺寸没变,媒体查询无从响应 - 被 JS 动态改写—— 初始设置后又被脚本覆盖,后续旋转完全失联
推荐写法:<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
@media (orientation: landscape) 单独用基本不可靠
它只看“逻辑宽度是否大于高度”,不关心物理朝向、地址栏是否收起、折叠屏是否半展开。真机上常出现:横屏了但 window.innerWidth <= window.innerHeight,导致查询不匹配。
立即学习“前端免费学习笔记(深入)”;
更糟的是,iOS 15+ 快速旋转可能跳过触发;Android Chrome v79+ 仅读取初始方向,后续旋转不再更新。
稳妥做法是组合判断:
@media (orientation: landscape) and (min-aspect-ratio: 1280/720)-
@media (max-height: 480px) and (min-width: 640px)—— 直接响应真实瓶颈(高度骤减)
别信桌面模拟器的 “Rotate” 按钮,测试必须用真机。
flex-direction 和 100vh/100vw 在方向切换后最容易翻车
这些值在横竖屏切换后基准突变,但 CSS 不会自动兜底,必须显式干预:
-
100vh在 iPhone 14 横屏下只剩 390px,内容常被截;改用100dvh,或降级为min-height: 100%+html, body { height: 100% } -
100vw在 iOS Safari 横屏时包含已隐藏地址栏高度,造成水平溢出;优先用100%或100dvw(注意 Android Chrome 100 以下不支持) -
flex-direction不会自动翻转;竖屏用column,横屏必须显式写row,否则子项仍堆叠 - 子项上的
margin在主轴翻转后行为错乱;统一改用gap,删掉所有margin-bottom、margin-right等固定方向边距
JavaScript 监听别用 orientationchange,改用 matchMedia
window.addEventListener('orientationchange', ...) 在 iOS 12+ 和现代安卓浏览器中已被废弃。它只反映陀螺仪角度,和实际 CSS 渲染方向脱节——比如应用强制竖屏,事件照发,但媒体查询根本不匹配。
正确做法是:
- 用
window.matchMedia('(orientation: landscape)')主动查询 - 监听
change事件:mql.addEventListener('change', e => { if (e.matches) { /* 横屏逻辑 */ } }) - 首次加载必须手动检查:
if (mql.matches) { /* 初始化横屏状态 */ }
真正复杂的地方不在写几个媒体查询,而在方向切换瞬间,100dvh 是否可用、gap 是否已生效、JS 是否拿到最新视口尺寸——这些都得在真机上逐帧验证,不能靠模拟器猜。


















