移动端rem,vw谁配原理

1,207 阅读3分钟

因为工作需要研究了一下移动端的适配原理,其实就是数学最简单的公式,当然更高深的物理像素还没有研究,仅仅作为入门级的rem,和vw适配,有问题大家可以讨论.
1、rem适配:
基本原理就是通过js动态修改html元素的字体大小,因为rem是一个相对于html字体大小来计算的相对单位,可以理解为rem是多少倍的px。

参数说明: screen.width:屏幕的宽度
designWidt:设计图的宽度
shouldShowWidth:应该现实的实际宽度
measurementWidth:设计图上测量出来的宽度

那么问题来了他是如何做到适配的呢?我根据自己的理解来说一说:

screen.width(px) / designWidth(px) = shouldShowWidth(px) / measurementWidth(px)

这个最简单的数学比例公式应该没有问题吧,要不然写出来就不是100%还原效果图了
那根据上面的公式,是如何得到下面的公式的,我根据自己的理解说一下

screen.width屏幕的宽度,一旦页面加载不可变化,固定
designWidth设计图的大小,固定比如750或者640(你喜欢就好)
其实我们要计算的是shouldShowWidth,在屏幕宽度固定,设计图固定的情况下他到底是多少
我们知道,屏幕大大小小,老老少少一堆,我们不能挨个去媒体查询吧(@media screen)不精确
那只有动态修改html的字体大小了,用rem是这样的...
拿来分析一下吧,我们得到了屏幕的宽度,设计图的宽度我们知道,拿来吧,还是他

screen.width(px) / designWidth(px) = shouldShowWidth(px) / measurementWidth(px)

measurementWidth这个宽度我们写的时候肯定是按照rem为单位写的,不能再按照px了吧,那就不适配了,div宽度300,你写300,iphone6s总共才375,你这一div就给占满了,但是实际他还不到设计图的一半(设计图750px
我刚才说过,其实适配就是rem和px的倍数关系,假设1rem = 100倍的px,那公式就是这样了
screen.width(px) / designWidth(px) = shouldShowWidth(px) / ((measurementWidth / 100)*1rem)
那么在以上在变化一下,是不是就是这样:
screen.width(px) / designWidth(px) = shouldShowWidth(px) / (measurementWidth*1rem/100)
再来变一下:
100 * (screen.width(px) / designWidth(px)) = shouldShowWidth(px) / measurementWidth*1rem
再来变一下:
100 * (screen.width(px) / designWidth(px)) = shouldShowWidth(px) / (measurementWidth(px)/100)rem
从而得出了以下公式:
也就是说,每次设计图实际量出来处于100就行了(也就是你假设的倍数)
当然如果你假设 1rem = 999px
999 * (screen.width(px) / designWidth(px)) = shouldShowWidth(px) / measurementWidth(px)/999(rem)
你每次量出来实际宽度,你去除999,我就不信你不用计算器,除以100多哈算额....

document.documentElement.style.fontSize = `${100 * (screen.width / designWidth)}px`

这样假设量出来设计图是354px那就口算一下,354px/100 = 3.54rem就可以了。

2、vw适配: vw我们都知道这是新的单位,相当于把屏幕平均分成了100份,如果看明白了上面,这就更好理解,更简单,也是公式,而且js都不需要,直接scss就行:(设计图假设750)

公式走起来

设计图测量宽 / 设计图 = 未知数Xvw / 屏幕宽度(100vw)

很简单变个形:

(设计图测量宽 / 设计图) * 屏幕宽度(100vw) = 未知数Xvw

在scss中直接来:
$px:实际测量的宽度
750:设计图宽度
100vh:屏幕宽度
如下方公式:<br/>
@function vw($px){
    @return ($px / 750) * 100vw
}
使用的时候直接

div{
    width:vw(300);
    height:vw(13);
}