横屏适配需用@media (orientation: landscape)重置布局,优先响应高度骤减(如iPhone 14横屏仅390px高),调整grid列数、字号、内边距,并避免vh依赖;真机需防系统UI干扰与浏览器延迟。

横屏时布局崩坏的典型表现
页面在手机横屏后,原本竖屏下正常的 3 列网格突然挤成一列、文字溢出容器、flex 项错位或高度塌陷,甚至出现横向滚动条——这不是 CSS 写错了,而是没为 orientation: landscape 单独设限。移动端横屏宽度虽变大,但视口高度骤减(比如 iPhone 14 竖屏是 844px 高,横屏只剩 390px),很多依赖 vh 或固定 height 的布局会直接失效。
用 @media (orientation: landscape) 重置关键尺寸
别只盯着宽度改,优先响应高度变化。常见做法是:在横屏下收缩行高、减小字体、压缩内边距,并把多列布局降为单列或双列。注意 orientation 媒体特性不触发重排,仅基于设备方向判断,兼容性极好(iOS Safari / Chrome / Firefox 全支持)。
- 避免用
min-width或max-width替代orientation,它们无法区分“宽屏手机横放”和“窄屏平板竖放” - 如果用了
grid-template-columns: repeat(3, 1fr),横屏时建议改为repeat(2, 1fr)或1fr -
font-size在横屏下可统一缩到clamp(14px, 2.5vw, 16px),比纯vw更稳
/* 横屏专用重置 */
@media (orientation: landscape) {
.card-grid { grid-template-columns: repeat(2, 1fr); }
.header { padding: 0.5rem 1rem; }
body { font-size: clamp(14px, 2.5vw, 16px); }
}为什么 vh 在横屏下特别危险
100vh 在横屏时等于屏幕**高度**(约 390px),但用户实际看到的是宽屏视图,导致内容被截断、按钮沉底不可点。更糟的是,iOS Safari 的 vh 在地址栏收起/展开时会动态变化,引发布局抖动。
- 替代方案:用
100dvh(支持现代 Safari / Chrome,但 Android WebView 旧版不认) - 稳妥方案:用
min-height: 100%配合html, body { height: 100% },再加overflow-y: auto - 绝对定位元素慎用
top: calc(100vh - 60px),横屏时计算值过小,直接贴顶
真机测试时容易漏掉的两个细节
模拟器里切横屏很流畅,但真机上常因系统 UI(如 iOS 控制中心下拉、Android 状态栏展开)临时改变视口尺寸,造成样式闪跳。另外,部分安卓浏览器(如 Samsung Internet)对 orientation 的触发有延迟。
立即学习“前端免费学习笔记(深入)”;
- 加一层防抖:用
window.addEventListener('resize', ...)监听并节流,配合matchMedia('(orientation: landscape)')主动查状态 - 横屏下禁用
user-scalable=no的 viewport 设置,否则用户双指缩放无法修正错位
横屏适配不是加个媒体查询就完事,核心是承认「同一设备在两种方向下,其实是两个不同的 UI 上下文」——列数、字号、留白、交互热区,都得重新权衡。最常被忽略的,是横屏时手指操作区域变窄,按钮间距反而要比竖屏更大才不容易误触。


















