@media (orientation: landscape) 单独使用不可靠,因它仅静态比较宽高比而不感知真实旋转、地址栏状态或分屏场景,必须配合 viewport 设置、宽度断点(如 min-width: 768px)和 dvh 单位才能稳定响应。

@media (orientation: landscape) 单独用在 iPad 上基本不可靠,必须搭配 width=device-width 的 <meta name="viewport">、明确的宽度断点(如 min-width: 768px)和动态单位(如 100dvh),才能稳定响应横竖屏切换。
为什么 @media (orientation: landscape) 经常不生效
它只看“逻辑宽是否大于高”,不感知真实旋转动作。iOS Safari 在分屏、Slide Over 或地址栏未收起时,window.innerWidth ,哪怕物理横握,<code>orientation: landscape 也不会匹配。Android Chrome v79+ 更只读取初始方向,后续旋转不再更新媒体查询状态。
- 漏掉
<meta name="viewport" content="width=device-width">—— 浏览器压根不触发方向重算 - 用
max-device-width而非max-width—— 现代浏览器已弃用 device-width,且受缩放、UA 欺骗干扰大 - 在桌面模拟器里测试成功,但真机失效 —— 模拟器“Rotate”按钮不等价于硬件旋转事件
真正能落地的写法:组合断点 + 宽高比兜底
不要只信 orientation,优先用宽度区间锚定 iPad,再叠加方向或宽高比过滤噪声。
- 竖屏 iPad:
@media (min-width: 768px) and (max-width: 768px) and (orientation: portrait)(注意:768px 是典型竖屏视口宽) - 横屏 iPad:
@media (min-width: 1024px) and (max-width: 1024px) and (orientation: landscape)(1024px 是典型横屏视口宽) - 更抗干扰的替代:
@media (min-width: 768px) and (max-width: 1024px) and (min-aspect-ratio: 12/9)——12/9(即 4/3)比16/9更兼容不同像素比的 iPad 型号 - 避免用
device-pixel-ratio做判断 —— 它和方向无关,且在 PWA 和 WebView 中行为不稳定
Flex/Grid 方向不会自动翻转,必须显式覆盖
CSS 不会因为你旋转了手机,就帮你把 flex-direction: column 切成 row。所有主轴相关属性都要手动重写。
- 竖屏导航用垂直堆叠:
.nav { display: flex; flex-direction: column; } - 横屏需改成通栏:
@media (orientation: landscape) { .nav { flex-direction: row; } } - Grid 布局同理:
grid-template-areas必须在两个方向媒体查询里分别定义,不能指望自动重排 - 注意
align-items在column下控制的是水平对齐,容易误以为“没生效”
100vh / 100vw 在 iPad 上最容易翻车
iPad Safari 横屏时 100vh 仍按竖屏高度计算,常导致内容被截;100vw 又可能包含已隐藏地址栏高度,造成横向溢出。
- 优先用
100dvh和100dvw(Safari 16.4+、Chrome 105+ 支持) - 降级方案:
html, body { height: 100%; }+min-height: 100%,但要注意嵌套 flex 容器需设height: 100%才能传递 - 字体大小别用纯
4vw—— 横竖屏切换时 iOS 不重绘,卡在旧尺寸;改用clamp(14px, 2.5vw, 16px)锁死区间
最常被忽略的其实是 viewport 标签是否被 JS 动态覆盖 —— 初始设置后又被脚本改写,后续方向变化就彻底失效。真机调试前务必检查 document.querySelector('meta[name="viewport"]').content 的实时值。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











