@media (orientation: landscape) 和 @media (orientation: portrait) 仅依据视口宽高比(innerwidth >= innerheight)判断方向,不依赖物理传感器;必须配合正确 viewport 标签(含 width=device-width)才生效,否则媒体查询完全失效;推荐叠加 min-width 或 min-aspect-ratio 提升准确性,并用 window.matchmedia() 动态监听,避免使用已废弃的 orientationchange 事件。

@media (orientation: landscape) 和 @media (orientation: portrait) 能用,但不能单独依赖——它只看视口宽高比,不反映真实旋转,且极易因 viewport 设置错误而完全失效。
viewport 标签写错,orientation 媒体查询就压根不工作
几乎所有“写了样式却没反应”的问题,根源都在 HTML 的 <meta name="viewport">。缺了、写错了、或被 JS 动态覆盖,@media (orientation: landscape) 就不会重新计算。
- 必须包含
width=device-width—— 缺了它,横屏时浏览器仍按竖屏逻辑渲染,orientation永远不匹配 - 禁用固定值,比如
width=375或width=414,否则横屏时视口宽度没变,媒体查询不会重算 - 推荐写法:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 注意:iOS Safari 和 Android Chrome 都依赖这个标签识别方向变化;PWA 或 iframe 嵌入时还可能受
Permissions-Policy限制
@media (orientation: landscape) 的触发条件很“表面”
它只判断 window.innerWidth >= window.innerHeight,不读陀螺仪、不看物理朝向。很多场景下会漏判或误判:
- 地址栏未隐藏(尤其 iOS Safari),导致横屏时
innerHeight变大,orientation: landscape不匹配 - 折叠屏半展开、分屏模式(Slide Over)、桌面端手动拉宽窗口,都会让宽高比“凑巧”满足或不满足
- 它不监听变化,只在浏览器完成 reflow 后延迟生效(几十毫秒),不是一转就切
- 稳妥做法是叠加条件:
@media (orientation: landscape) and (min-width: 480px)或更准的@media (min-aspect-ratio: 1280/720)
window.matchMedia('(orientation: landscape)') 是唯一可靠的 JS 监听方式
window.addEventListener('orientationchange', ...) 已废弃多年,iOS 12+ 和所有现代安卓浏览器都不再保证其与 CSS 渲染同步。它只读传感器角度,和实际视口方向脱节。
- 正确做法:
const mql = window.matchMedia('(orientation: landscape)'); - 监听变更:
mql.addEventListener('change', e => { if (e.matches) { /* 横屏逻辑 */ } }); - 首次加载必须手动检查:
if (mql.matches) { /* 初始化横屏状态 */ },否则直出横屏页面会跳过初始样式 - 不要用
screen.orientation.type—— 在 iframe 中常被禁用,且部分 WebView 不支持
更稳的替代方案:用 width/height + aspect-ratio 组合判断
如果项目需兼容旧设备或对稳定性要求极高,直接放弃 orientation 是更务实的选择。
- 横屏倾向常用:
@media (min-width: 600px) and (max-height: 400px) - 竖屏倾向常用:
@media (max-width: 480px), (min-height: 600px) - 现代浏览器(Safari 15.4+、Chrome 88+、Firefox 89+)可用
aspect-ratio:@media (min-aspect-ratio: 1/1)表示宽 ≥ 高,语义更清晰、响应更及时 - 注意:
aspect-ratio在旧环境无回退,必须搭配降级规则,例如:@media (orientation: landscape), (min-aspect-ratio: 1/1)
真正容易被忽略的是:横竖屏切换时 DOM 结构不变,但 100vw 在 iOS 横屏下会包含已隐藏的地址栏高度,导致内容被切掉;另外,纯 CSS transform: rotate(90deg) 会让触摸坐标错乱,pointer-events: none 又会禁用交互——这些细节不测真机根本发现不了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











