必须配对 viewport 设置、手动初始化匹配状态、加宽高比兜底,否则真机上@media (orientation: landscape)大概率不触发;推荐viewport设width=device-width,并用screen.orientation或matchmedia+resize降级检测,css类切换更可控。

@media (orientation: landscape) 单独写基本没用,必须配对 viewport 设置、手动初始化匹配状态、加宽高比兜底,否则真机上大概率不触发。
viewport 标签写错,@media (orientation: landscape) 就压根不计算
iOS Safari 和 Android Chrome 都依赖 <meta name="viewport"> 才会识别方向变化。漏掉 width=device-width,浏览器就按固定宽度渲染,@media (orientation: landscape) 永远不会进入匹配状态。
常见错误包括:
-
width=375这类固定值 —— 视口宽度锁死,旋转后无法重算媒体查询 - JS 动态覆盖初始
<meta>标签 —— 后续旋转失效 - 只写
initial-scale=1.0却缺width=device-width
推荐写法:<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
只靠 orientation 媒体查询,横屏样式大概率延迟或漏掉
它不是实时响应物理旋转,而是在浏览器完成 reflow 后才重新计算,通常有几十毫秒延迟。更关键的是:判定逻辑只是 if (window.innerWidth > window.innerHeight),和传感器无关。
横屏时若地址栏未收起、折叠屏半展开,window.innerWidth ,<code>orientation: landscape 可能根本不匹配。
稳妥做法是组合判断:
@media (orientation: landscape) and (min-aspect-ratio: 1280/720)-
@media (max-height: 480px) and (min-width: 640px)—— 直接响应真实瓶颈(高度骤减)
别信桌面模拟器的 “Rotate” 按钮,测试必须用真机。
横屏时 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)锁死区间
更稳的方案:用 screen.orientation API 主动管理
@media (orientation: ) 在绝大多数实际场景中不可靠,不能作为主力方案。优先检测原生 API 是否可用,再绑定监听:
if ('orientation' in screen) {
const updateLayout = () => {
document.body.className = screen.orientation.type.startsWith('portrait')
? 'orientation-portrait'
: 'orientation-landscape';
};
screen.orientation.addEventListener('change', updateLayout);
updateLayout(); // 关键:补初始化,否则首屏样式错乱
} else {
// 降级 fallback:用 matchMedia + resize 粗略判断
const mq = window.matchMedia('(min-aspect-ratio: 1/1)');
const updateByMq = () => {
document.body.classList.toggle('orientation-landscape', mq.matches);
};
mq.addEventListener('change', updateByMq);
updateByMq();
}
CSS 类切换比媒体查询更可控,把方向状态转为 class 写在 上,后续所有样式都基于它 —— 避免重复写 @media 块,还能叠加其他状态、配合 transition 做平滑过渡。
真正麻烦的不是怎么写样式,而是怎么让“横屏”这件事在不同设备、不同加载时机、不同 UI 栏状态下,都被稳定识别出来。viewport 是门槛,screen.orientation 是基线,dvh 和 clamp() 是细节兜底 —— 少一个环节,横屏样式就可能在某个用户手里彻底消失。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











