viewport标签写错会导致@media (orientation: landscape)失效,根源在于iOS Safari和Android Chrome依赖其正确配置识别方向变化;必须写width=device-width且不可被JS动态覆盖,否则横竖屏样式均不触发。

viewport 标签写错,@media (orientation: landscape) 就不会触发
几乎所有横竖屏样式不生效的问题,根源都在 <meta name="viewport">。iOS Safari 和 Android Chrome 都依赖它识别方向变化,缺了或写错,媒体查询压根不计算。
常见错误包括:
- 漏掉
width=device-width—— 缺它,横屏时浏览器仍按竖屏宽度渲染,orientation永远不匹配 - 用了固定值如
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,查询就直接跳过。
立即学习“前端免费学习笔记(深入)”;
更稳妥的写法是组合判断:
@media (orientation: landscape) and (min-width: 480px)-
@media (max-height: 480px) and (min-width: 640px)—— 直接响应真实瓶颈(高度骤减) - iPad 场景建议:
@media (min-width: 768px) and (max-width: 1024px) and (orientation: landscape)
别只靠 orientation,真机测试前务必叠加尺寸断点。
横屏时 100vh、flex-direction、font-size 最容易翻车
这些值在方向切换后基准突变,CSS 不会自动兜底,必须显式干预:
-
100vh在 iPhone 14 横屏下只剩 390px,常导致内容被截;改用100dvh(动态视口高度),或降级为min-height: 100%+html, body { height: 100% } -
flex-direction不会自动翻转;竖屏用column,横屏必须显式写row,否则子项仍堆叠 -
font-size: 4vw横屏暴增;改用clamp(14px, 2.5vw, 16px)锁死区间
注意:justify-content 和 align-items 的语义随主轴变化而反转,方向一换就得同步调整。
JavaScript 监听别用 orientationchange,改用 matchMedia
window.addEventListener('orientationchange', ...) 在 iOS 12+ 和现代安卓浏览器中已被废弃。它只反映陀螺仪角度,和实际 CSS 渲染方向脱节——比如平板横放但应用强制竖屏,事件照发,但媒体查询根本不匹配。
正确做法是:
- 主动查询:
const mql = window.matchMedia('(orientation: landscape)') - 监听变更:
mql.addEventListener('change', e => { if (e.matches) { /* 横屏逻辑 */ } }) - 首次加载也要手动检查:
if (mql.matches) { /* 初始化横屏状态 */ }
真机旋转比模拟器可靠得多;Chrome DevTools 的 “Rotate” 按钮不等价于真实旋转,测试必须上真机。


















