一、rem和px转换原理:
1、若元素的宽度使用rem为单位,该元素在浏览器页面中的实际宽度单位为px,宽度的值计算公式为:
比如:
最终在浏览器加载页面后div的宽度为:20 * 0.5=10px
那么反过来,css中元素的rem值的计算公式也就是:
可以理解为css中元素rem的值实际就是浏览器页面中元素的px值与html的font-size的px值的比例。
2、使用了rem为单位的元素都会根据html的font-size的值计算盒模型的尺寸(px单位),当改变html的font-size,所有使用了rem的元素的也跟着重新计算。例如:原本页面html的font-size大小为17.664px
在控制台中直接将html的font-size设置为40px后,使用了rem的元素都重新计算,尺寸也变大,对比上图页面样式变化如下:
3、开发时,UI稿上元素的px值,在css中为多少rem?
假设:设计稿宽度为375px,设计稿上的元素尺寸为20px,屏幕宽度为375px(也就是设计稿与屏幕1:1),
在css文件中若将html的font-size为37.5px,那么根据第1点中提到的 rem计算公式,到css文件中元素的宽度值为:20 / 37.5 rem。
但实际中手机屏幕宽度不只有375px这一个尺寸,那要怎么做的手机屏幕比较宽时,元素的宽度按比例变宽呢?
4、根据屏幕的宽度与设计稿的比例,计算不同宽度屏幕下html的font-size,屏幕宽度变大或者变小,html的font-size按比例变大变小,使用了rem为单位的元素的宽度,也会随着html的font-size的变化而变化。
根据屏幕宽度与设计稿的比例,计算html的font-size
设计稿宽度px / 屏幕的宽度px = 与设计稿等宽时的html的fontsize / x
与设计稿等宽时的html的fontsize:可以自己设定,最好选择比较好计算的37.5px
x :就为 不同屏幕宽度对应的html的font-size的值
js代码:
二、问题情景:
加载页面瞬间有一个缩放的过程,问题出现的原因:
(1)首先浏览器加载css,加入css中将html元素的fontsize设置为16px。
然后在去加载后面的dom元素,这时浏览器按照html的16px,计算dom元素单位为rem的样式属性的px值,渲染一遍dom元素。
(2)浏览器执行到我们加的计算html font-size的js代码,绑定了DOMContentLoaded 事件,在dom加载完成触发事件监听器又将html的font-size设置为22.08px。
浏览器会根据这个值又重新计算所有dom元素使用了rem的样式属性,导致了重绘,才会有加载页面瞬间缩放的现象。
解决办法
(1)在head中立即执行将js计算html元素font-size的方法recalc
分析:加载完css文件,css文件中将html元素的font-size设置为16px后,在head中立即执行recalc方法(此时dom元素还没有加载),将html元素的font-size设置为22.08px,等到加载渲染dom元素时,是按照最终的22.08px计算单位为rem的样式属性,就不会在出现上面缩放现象。
番外一:
如果仍保留在DOMContentLoaded事件中执行recalc方法,但是把css文件中html的font-size设置为与UI稿中的大小相近(37.5px),缩放现象也会改善,但是这样只能保证与UI稿尺寸一致的屏幕。
番外二:
异步图片,加上占位尺寸,否则会影响到后面的dom元素,图片加载前、后,图片后面的元素会重新计算位置,影响性能。
三、某些浏览器rem计算不准确的问题
问题:存在部分安卓手机的部分浏览器(如小米qq、魅族原装、华为自带浏览器等)存在rem计算有问题,导致页面元素整体宽度偏大与样式不一致
解决方案一:
将宽度、边距的rem修改为百分比或者考虑弹性盒布局,高度最好由被内部元素撑开,否则也需要兼容高度的rem计算不准确问题。width: 5rem; 改为: width: 50%;
解决方案二:
根据不兼容的浏览器按照对应比例缩小html 的font-size的大小,可以参考这篇文章的思路:
http://www.ccc5.cc/2145.html