横屏内容被裁剪主因是误用100vh/100vw且未配viewport标签或未处理视口动态变化;iPhone 14横屏时100vh仅约390px,Android地址栏未收起时vh仍含UI高度,导致容器撑不满、子项被截;应改用min-height: 100dvh并确保viewport含width=device-width,配合max-height/min-width断点及真机测试。

直接说结论:横屏内容被裁剪,90% 是因为用了 100vh 或 100vw,且没配 viewport 元标签或没处理真机视口动态变化。
为什么 100vh 在横屏下会切掉内容
iPhone 14 横屏时 100vh 实际只有约 390px,远小于竖屏的 844px;Android 部分机型横屏后地址栏未收起,vh 还按“含地址栏高度”计算,导致容器撑不满、子元素被截。这不是 CSS 写错了,是单位基准失效了。
- 改用
min-height: 100dvh(动态视口高度),iOS Safari 15.4+ 和 Chrome 100+ 支持;降级方案:min-height: 100%+html, body { height: 100%; } - 避免对根容器设
height: 100vh,尤其当内部有 flex 布局时,父容器高度不足会直接压扁子项 - 真机测试时,键盘弹出再收起瞬间,
visualViewport.height有几十毫秒延迟,JS 读取可能拿到旧值——别在resize里直接靠window.innerHeight重设高度
@media (orientation: landscape) 为什么没生效
这个媒体查询不看手机物理朝向,只比对“逻辑宽高比”。如果横屏时地址栏没收起、折叠屏半展开、或者 viewport 标签写错,orientation: landscape 就永远不匹配。
- 必须确保
<meta name="viewport" content="width=device-width">存在,漏掉width=device-width是最常见失效原因 - 禁用固定值写法,比如
width=375—— 视口宽度不变,浏览器无依据重算方向 - 更可靠写法:
@media (max-height: 480px) and (min-width: 640px),直击横屏时高度骤减的真实瓶颈,兼容性更好 - 别依赖
window.orientation或废弃的orientationchange事件,改用window.matchMedia('(orientation: landscape)')监听
Flex 布局在横屏下错位或溢出
flex-direction 不会自动从 column 切成 row,align-items 在子项高度不一致时会因基线不同显得歪斜,white-space: nowrap + flex-shrink: 0 容易让导航栏撑爆容器。
立即学习“前端免费学习笔记(深入)”;
- 横屏需显式声明:
@media (orientation: landscape) { .container { flex-direction: row; } } - 子项高度不一致时,
align-items: center显得错位?先统一子项min-height,或换display: grid+align-items: stretch - 横向滚动导航:把
white-space: nowrap换成flex-wrap: wrap,项目设flex: 0 0 calc(50% - 8px)+gap: 16px,比用margin-right更稳 - 若坚持单行滚动,加
max-width: 100vw防容器暴增,同时保留overflow-x: auto
真正容易被忽略的是:iOS Safari 和 Android WebView 对 flex-basis 的解析不一致,模拟器里看着正常,真机上 computed 样式可能完全不同——横屏适配必须上真机测,不能只靠 DevTools 的 Rotate 按钮。


















