h5端横屏适配必须用css+js主动干预,因pageorientation在h5不生效;需通过transform旋转容器、宽高互换、动态class切换及rpx基准调整来实现可靠适配。

uni-app 的 H5 端无法通过 manifest.json 或 pages.json 中的 pageOrientation 配置生效——这些只对 APP 和小程序有效。H5 端必须靠 CSS + JS 主动干预,否则用户一横屏,750rpx 宽度突然变高、Flex 流向错乱、字体缩放失真,页面直接“散架”。
为什么 @media (orientation: landscape) 经常不生效?
这不是写法错,而是浏览器在移动端对 orientation 媒体查询的触发逻辑有坑:
- 部分 Android 浏览器(尤其旧版 UC、QQ 浏览器)根本不触发该媒体查询
- 即使触发,
window.innerWidth和window.innerHeight在横屏后可能未及时更新,导致 CSS 计算仍按竖屏尺寸进行 - 更关键的是:CSS 里写
.container { flex-direction: column; }后,在@media (orientation: landscape)里重写flex-direction: row;,若原选择器权重更高或存在缓存,新样式会被忽略
实操建议:删掉基础样式中的布局声明,把所有方向相关样式都收进媒体查询里;加 !important 临时兜底(仅调试用);优先用 window.matchMedia 替代纯 CSS 查询。
如何用 JS 可靠检测并响应横屏?
比依赖 @media 更稳的方式是监听 resize + 手动判断宽高比,并主动切换 class:
- 用
uni.onWindowResize(推荐)或原生window.addEventListener('resize', ...),避免漏掉首次加载时的方向判断 - 判断逻辑必须用
res.size.windowWidth > res.size.windowHeight,而非window.orientation(已被废弃且 iOS 不支持) - 不要直接操作 DOM 样式,统一加/删一个
landscape类,所有横屏样式走.landscape .xxx选择器
示例:
onLoad() {
this.checkOrientation()
uni.onWindowResize(res => {
this.checkOrientation(res)
})
},
methods: {
checkOrientation(res) {
const { windowWidth, windowHeight } = res?.size || uni.getSystemInfoSync()
const isLandscape = windowWidth > windowHeight
uni.$emit('orientationChange', { isLandscape })
this.$nextTick(() => {
document.body.classList.toggle('landscape', isLandscape)
})
}
}
H5 强制横屏的唯一可行方案:CSS3 transform 旋转容器
想让 H5 页面“看起来是横屏”,只能放弃改变 viewport 方向(浏览器不给权限),改用视觉欺骗:
- 把
或根<view></view>整体顺时针旋转 90°,再用width/height互换 +transform-origin调整锚点 - 必须同时设置
overflow: hidden和固定视口高度,否则滚动错乱 - 注意:video、canvas、input 等原生组件会因 transform 失去交互区域,需单独重定位或隐藏
关键 CSS(仅用于特定页面,如视频全屏页):
.force-landscape {
position: fixed;
top: 0;
left: 0;
width: 100vh;
height: 100vw;
transform: rotate(90deg);
transform-origin: top left;
overflow: hidden;
}
@media (orientation: landscape) {
.force-landscape {
transform: none;
width: 100vw;
height: 100vh;
}
}
最容易被忽略的细节:rpx / upx 在横屏下失效
uni-app 的 rpx 单位基于设计稿宽度(默认 750)等比缩放,但它的基准始终是 window.innerWidth。横屏后,这个值变大,100rpx 可能从 50px 涨到 87px,文字和按钮突然“发福”。这不是 bug,是设计使然。
解决思路只有两个:
- 放弃全屏 rpx,关键字号/间距改用
px或em,配合媒体查询做断点 - 横屏时动态修改根字体大小:
document.documentElement.style.fontSize = window.innerHeight / 750 * 100 + 'px',让 rpx 基准重回合理范围
别指望一次配置通吃所有机型。H5 横屏适配本质是“降级兼容”:能看、能点、不溢出,就是成功。











