浅谈rem布局和vm布局


  • 基础概念

屏幕尺寸

屏幕对角线的长度(cm)

屏幕像素密度

屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算(PPI)。

屏幕分辨率

横纵向上物理像素的个数(物理像素)

物理像素(physical pixel)或设备像素(device pixel)

物理像素又被称为设备像素,它是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度透明度,通过控制每个像素点的颜色,使屏幕显示出不同的图像,屏幕从工厂出来那天起,它上面的物理像素点就固定不变了,单位pt。

设备独立像素(density-independent pixel)

设备独立像素也称为密度无关像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素),然后由相关系统转换为物理像素。

css像素或者逻辑像素或者设备无关像素(device-independent pixel)

CSS像素又称为逻辑像素或者与设备无关的像素(device-independent pixel),简称DIPs,是web开发者使用的最小单位,也就是我们经常写的width=多少px中的px

设备像素比(device pixel ratio)

设备像素比 = 物理像素 / 设备独立像素

在Javascript中,可以通过 window.devicePixelRatio 获取到当前设备的dpr。

在css中,可以通过 -webkit-device-pixel-ratio-webkit-min-device-pixel-ratio和 -webkit-max-device-pixel-ratio进行媒体查询,对不同dpr的设备,做一些样式适配。

或者使用 resolution | min-resolution | max-resolution 这些比较新的标准方式

上图中, Retina为高清设备屏幕,它的一个css像素对应 了4个物理像素

位图像素

一个位图像素是栅格图像(如:png, jpg, gif等)最小的数据单元。每一个位图像素都包含着一些自身的显示信息(如:显示位置,颜色值,透明度等)。

理论上,1个位图像素对应于1个物理像素,图片才能得到完美清晰的展示

如上图:对于dpr=2的retina屏幕而言,1个位图像素对应于4个物理像素,由于单个位图像素不可以再进一步分割,所以只能就近取色,从而导致图片模糊(注意上述的几个颜色值)。

所以,对于图片高清问题,比较好的方案就是两倍图片(@2x)。

如:200×300(css pixel)img标签,就需要提供400×600的图片。

缩放比 scale

缩放比:scale = 1/dpr

整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:设备的物理分辨率/(devicePixelRatio * scale),在scale为1的情况下,device-width = 设备的物理分辨率/devicePixelRatio 。这就是initial-scale的意义

视窗 viewport

简单的理解,viewport是严格等于浏览器的窗口。在桌面浏览器中,viewport就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。

移动端的viewport太窄,为了能更好为CSS布局服务,所以提供了两个viewport:虚拟的visualviewport和布局的layoutviewport。

viewport的内容比较深,推荐阅读PPK写的文章,以及中文翻译

视窗缩放 viewport scale

在开发移动端页面,我们可以设置meta标签的viewport scale来对视窗的大小进行缩放定义

rem单位

font size of the root element.

rem就是相对于根元素font-size来做计算

视窗单位

  • vw : 1vw 等于视窗宽度的1%
  • vh : 1vh 等于视窗高度的1%
  • vmin : 选取 vw 和 vh 中最小的那个
  • vmax : 选取 vw 和 vh 中最大的那个

兼容性:在移动端 iOS 8 以上以及 Android 4.4 以上获得支持

可以去 Can I use 或 css3test 查看兼容情况

关于设计稿为什么要使用二倍图、三倍图

理论上一个位图像素对应一个物理像素,图片才能完美显示!设计稿是按px单位设计的,为了应对高分辨率显示屏(设备像素比 dpi  = 2或者3等)的高像素密度==>同等px大小拥有dpi倍的物理像素点,我们将设计稿增大 dpi倍,一般是2被或者3倍,这样设计稿缩放到屏幕时的分辨率就和屏幕本身的分辨率一致了(实际中设计稿总像素数要大于或者等于屏幕分辨率就可以),图片就可以完美显示了,

移动端app设计以什么尺寸作为视觉稿作为适配(以淘宝为什么用iphone 6作为设计稿参考基准屏幕为例)

https://zhidao.baidu.com/question/1695418267113361468.html

假如公司设计稿不是基于750的怎么办,其实很简单,按上图做一些相应替换即可,但是流程和方法还是一样的。解释一下为什么要在@3x的图里切,这是因为现在市面上也有不少像魅蓝note这种超高清屏幕,devicePixelRatio已经达到3了,这个切图保证在所有设备都清晰显示。

rem布局原理

rem布局的本质是什么?我觉得rem的本质就是“等比缩放”,要是元素会随着页面尺寸的变化,宽度和高度等比缩放,不就可以在维持原有布局的基础上最好的适配各种屏幕尺寸了吗。

假设我们将屏幕宽度平均分成100份,每一份的宽度用x表示,x = 屏幕宽度 / 100,如果将x作为单位,x前面的数值就代表屏幕宽度的百分比,元素大小就会随页面尺寸同步缩放!

如果想要页面元素随着屏幕宽度等比变化,我们需要上面的x单位,不幸的是css中并没有这样的单位,幸运的是在css中有rem,通过rem这个桥梁,可以实现神奇的x
如果子元素设置rem单位的属性,通过更改html元素的字体大小,就可以让子元素实际大小发生变化。如果让html元素字体的大小,恒等于屏幕宽度的1/100,那1rem和1x就等价了(实际上我们只要让rem与屏幕尺寸挂钩就好了,不一定将其设为屏幕尺寸的1/100)

如何设置html根元素的尺寸

设备屏幕尺寸/设计稿尺寸 =  页面元素实际尺寸/元素设计稿尺寸(等比缩放) =====>页面元素实际尺寸=元素设计稿尺寸*(设备屏幕尺寸/设计稿尺寸 )

上面标红的系数就是我们想要的rem单位的值,也就是html根元素的字体大小! ====>font-size = 设备屏幕尺寸/设计稿尺寸  px。考虑到一般浏览器的最小字体是12px,如果设备屏幕尺寸是320px,设计稿宽度是640px,则html的字体大小就是320/640 = 0.5px,这个字体大小在浏览器的无法正常显示,所以一般*100,这样html的字体大小就变成50px,就解决了字体大小小于12px的问题(其实感觉这个系数是10也可以,虽然计算出来的html字体大小是5px小于12px,但是实际中在页面中并没有使用这个尺寸的文字,因为每个元素都有自己设置相应的字体大小,不会继承html的字体,所以好像也不用担心系数10太小的问题);

此外也方便了计算,设计稿尺寸转rem尺寸时只要在原来的数值上除以100就可以了,如果除以非10的整数不好计算。

最终 html字体大小 font-size = 1rem = (设备屏幕尺寸/设计稿尺寸)*系数(例如100)

可以通过js来设置,一般需要在页面dom ready、resize和屏幕旋转中设置  

1、font-size  = (document.documentElement.clientWidth /designWidth)*系数

2、设计稿尺寸转rem尺寸时只要在原来的数值上除以就可以了

 

参看:https://link.jianshu.com/?t=http://link.zhihu.com/?target=http%3A//www.cnblogs.com/lyzg/p/4877277.html