rem方案中根字体大小动态计算后页面元素错位怎么办?

欣辰(打工版) 阅读 50

我按照教程用JS动态计算rem,但手机旋转屏幕后文字和图片比例不对,有时候文字太大或太小。

代码检查了好几遍没问题,是不是哪里漏了?比如这个计算函数:

function setRem() {
  const width = document.documentElement.clientWidth;
  const fontSize = width / 19.2;
  document.documentElement.style.fontSize = `${fontSize}px`;
}
window.addEventListener('resize', setRem);
setRem();

在iPhone12上调试时发现,竖屏正常,横屏后输入框宽度变成100%却超出屏幕,可能是rem基准值没重算?或者需要考虑设备像素比?

我来解答 赞 12 收藏
二维码
手机扫码查看
2 条解答
极客美荣
你这个计算方式没考虑设备像素比,而且resize事件触发时机可能不对。试试用orientationchange事件强制重算,加上setTimeout延迟执行setRem:

window.addEventListener('orientationchange', () => {
setTimeout(setRem, 300);
});


另外计算时要乘以devicePixelRatio:

function setRem() {
const width = document.documentElement.clientWidth * window.devicePixelRatio;
const fontSize = width / 19.2;
document.documentElement.style.fontSize = ${fontSize}px;
}
点赞 7
2026-02-03 00:52
♫娜娜
♫娜娜 Lv1
问题出在横屏时 window.resize 事件触发后,document.documentElement.clientWidth 没有及时更新导致的。尤其是 iPhone 这种设备,会有地址栏显示/隐藏的问题,影响了视口宽度计算。

解决办法是加个延迟处理,让系统先把视口宽度调整完再算 rem:
function setRem() {
const width = document.documentElement.clientWidth;
const fontSize = width / 19.2;
document.documentElement.style.fontSize = ${fontSize}px;
}

// 加个防抖和延迟确保视口计算准确
let timeoutId;
window.addEventListener('resize', () => {
clearTimeout(timeoutId);
timeoutId = setTimeout(setRem, 200); // 延迟200ms再执行
});

setRem();


另外,设备像素比一般不影响 rem 计算,主要还是视口宽度的问题。调试看看这样改了后是不是正常了,不行再调延迟时间。横屏竖屏切换这事儿确实挺烦人的,写个通用方案还得考虑各种奇葩情况。
点赞 5
2026-01-28 23:04