Android端Google Chrome浏览器旋转与Canvas调整大小时innerWidth/innerHeight返回异常值问题咨询
我在Android设备的Google Chrome浏览器里碰到了一个诡异的视口尺寸异常问题,折腾了好一阵才找到解决办法,下面把整个过程和原因拆解清楚:
问题场景与复现代码
我用一个仅包含Canvas元素的空白页面,通过以下代码获取视口宽高并设置Canvas的CSS宽高,让它铺满整个页面:
<canvas id="canvas"></canvas> <script> window.onresize = function() { let ScreenWidth = window.innerWidth; let ScreenHeight = window.innerHeight; console.log("w: " + ScreenWidth); console.log("h: " + ScreenHeight); let canvas = document.getElementById('canvas'); // 问题疑似和这段代码关联 canvas.style.width = ScreenWidth + "px"; canvas.style.height = ScreenHeight + "px"; }; // 首次触发resize事件 window.dispatchEvent(new Event('resize')); </script>
这段逻辑在PC端完全正常,但在Android Chrome里出现了异常:
- 首次触发resize,控制台打印
360、649(符合预期的竖屏视口尺寸) - 旋转手机到横屏,resize事件触发,打印
705、274(受浏览器地址栏影响,属于合理范围) - 再旋转回竖屏时,打印值变成了
705、1271,完全不是预期的360、649 - 移除设置Canvas宽高的代码后,旋转手机时宽高值能在
360、649与705、274间正常切换,异常消失
解决办法:修改viewport元标签
我尝试调整了viewport元标签,添加minimum-scale=1后,异常问题直接消失了:
- 原标签:
<meta name="viewport" content="width=device-width, initial-scale=1">
- 修改后标签:
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1">
为什么添加minimum-scale=1能解决问题?
这其实是Android Chrome的自动缩放机制在搞鬼:
当你把Canvas设置为当前视口尺寸后,旋转手机时,浏览器会认为页面内容(也就是这个Canvas)的尺寸超过了新视口的范围,于是自动缩小页面来适配。但这个缩放操作会被浏览器“记住”,当你切回原方向时,它没有把缩放比例恢复到1倍,反而保留了之前缩小后的比例。
而window.innerWidth/innerHeight的数值是基于当前浏览器缩放后的视口计算的——当页面被缩小,视口的计算尺寸就会变成“原视口尺寸 ÷ 缩放比例”,所以才会出现数值异常变大的情况。
添加minimum-scale=1的作用,就是强制浏览器不允许页面被缩小到1倍以下。这样一来,旋转手机时浏览器没法自动缩小页面,也就不会留下错误的缩放状态,切回原方向时,视口尺寸就能正常还原成初始值了。
你提到MDN说innerWidth反映实际视口而非内容宽度,这点完全没错——但这里的“实际视口”是受浏览器缩放比例影响的,当页面被自动缩放后,视口的计算自然会跟着变化,这就是异常的根源。
内容的提问来源于stack exchange,提问作者Tornseglare

