vw+rem实现移动端自适应——最简单的自适应写法
前言:关于移动端自适应,有很多种实现方式,包括 js初始化、meta标签设置、css标签设置等一种或多种方式的组合。有些方法在我看来过于繁琐,今天我们来讨论一种非常简单的,仅需要几行css代码和一个计算器就能实现的移动端自适应方法。
一、几个重要概念(物理像素、css像素、DPR):
1、物理像素:顾名思义,手机(写起来更亲切,后面就用手机代指移动端了)生产的时候,屏幕上的像素点(此处像素点是一个模糊化的概念,理解就好)个数即为物理像素,以iphone6为例(后面就用ip6代指手机 [/滑稽]),横向物理像素点为750px,纵向1334px。
2、css像素:手机执行显示任务的时候,我们编写代码时设置的css像素的大小。举个例子:当我们需要在ip6上显示一个满屏宽的div时,我们需要设置div的width为375px;
3、DPR:物理像素/css像素 = DPR ,当然,这是我的个人浅显理解,欢迎大神指正。
问:为什么有物理像素和css像素的区分呢?
答:个人理解是,物理像素当然越大越好,越大代表着设备可以显示的像素的点越多,那么屏幕就更高清。但如果本身屏幕很小,而物理像素很大,用物理像素去显示内容,那岂不是还要拿着放大镜才看得清?所以就需要有DPR的存在,即物理像素与css像素比,换个说法:多少个物理像素显示一个css像素。
二、需要的css属性(vw、rem):
1、vw: vw同样为相对单位,vw将屏幕宽度均等的分为100份,100vw即为当前设备的满屏css像素宽度,在ip6中: 100vw = 375px(css像素);
2、rem:相对根节点字体大小,一个相对单位。这么说不好理解,举个例子:
:root{ font-size: 30px; } div{ width:1rem; }
上述代码中:我们设置根标签(:root === html)字体大小为30px,接下来我们设置该页面的div元素宽度为1rem,那么div的宽度即为30px。同理,想要设置div宽度为60px,写2rem即可。
三、需求与计算方式(以ip6为例):
1、我们的需求:设计师给的设计稿为750px精度,标准的ip6尺寸,我们在编写页面时想要统一将尺寸写成rem,且与设计稿的比例是1:100,即: 设计稿标注100px = css代码1rem(不要纠结为什么1:100,重点在于自适应);
2、计算过程:
已知 100vw = 375px(css像素),那么 1vw = 3.75px(css像素);
已知设计稿的 100px(物理像素) = 1rem,根据ip6为2的DPR值可以轻易得出:1rem = 50px(css像素);
1rem = ?vw ——————> 50/3.75 = 13.333333333333...
综上:我们只需要将根节点字体大小设置为 13.333333333333vw ,接下来编写css时使用rem作为单位定义像素大小,即可以实现整个以ip6为标准尺寸设计稿的页面在全部移动端设备上的自适应了;
3、原理:利用了vw是相对设备屏幕尺寸大小的单位的方式实现。
四、具体实践(上面原理没看懂的同学也没关系,下面给出一份以ip6为设计稿的项目代码的基础css配置):
:root{ margin: 0; padding: 0; list-style: none; font-size: 13.333333333333333333vw; } body{ font-size: 0; } :root,body,#root{ height: 100%; width: 100%; } .App{ font-size: 0.3rem; width: 100%; height: 100%; }
需要解释的是:body标签专门设置了一个font-size为0,这个是为了消除子元素标签间的间隔。
#root和.App则是自行定义的id和class选择器了,我想要初始化字体大小为30px,所以在 .App 中加上了 font-size:0.3rem。
五、结尾
我们来看看效果
上面的一个盒子是用rem作为单位写出来的,下面使用px,二者在ip6上同样都表现为100px的正方形。(有人会疑惑为什么这个地方是2rem而不是1rem,因为在设计稿的750px宽的图上,这个正方形是200px的)
当我们把设备换成iPad Pro之后,他们就变成了下面这样:
可以看到,红色的盒子的确实现了自适应。