css单位之——rem与vw/vh要点辨析

*** 以下均以 2倍于 iphone6/7/8设备尺寸 的设计图(图宽 750px) 为例 ***
*** html根元素fontsize:50px ***
*** E元素(需要转化单位) ***

 

首先介绍一下2种分辨率的问题???

物理分辨率(基于硬件层,又称 标准分辨率或真实分辨率):显示屏的 最佳分辨率,即屏幕实际存在的像素行数乘以列数的数学表达方式,是显示屏 固有的参数,不能调节,其含义是指显示屏 最高可显示的像素数。

逻辑分辨率(基于系统层,详见1    详见2)是页面上抽象的像素点的多少,其单位为dpi(dot per inch),其大小和UI设计者有关。

两者间由 Scale Factor(缩放因子) 计算得到,通常 物理分辨率 > 逻辑分辨率,而 物理分辨率 = 逻辑分辨率 * 缩放因子;但在使用 台式电脑、和 笔记本 的情况下 物理分辨率 = 逻辑分辨率。

以苹果设备为例:

css单位之——rem与vw/vh要点辨析_第1张图片

css单位之——rem与vw/vh要点辨析_第2张图片

3.5"、4"等物理尺寸是指屏幕的实际大小。大的屏幕同时必须要配备高物理像素(px)分辨率,也就是在这个尺寸下可以显示多少个像素(px),显示的像素越多,可以表现的余地自然越大。PPI 指 每寸屏幕能容纳多少颗像素,用于描述屏幕的 像素密度。

总结:iphone6/7/8逻辑像素(pt)分辨率为375*667,scale(单位长度 内的(pixel/point)数量比)为@2X。所以要在iphone6/7/8上正常显示,设计稿的物理像素(px)分辨率需要是750*1334.

rem介绍:

1rem = 根元素html的font-size值(px)。由上例,此处1rem = 50px。px大小就如同cm一样,其大小是一定的,并不会受设备尺寸的影响!

当页面中所有元素都使用rem单位时,你只需要增加一小段js代码,通过监听设备尺寸来改变根元素的font-size值,那么所有元素就会按比例放大或者缩小,以此最大程度地在各个尺寸屏幕上还原设计稿。但这种方案有弊端(弊端之一:和根元素font-size值强耦合,系统字体放大或缩小时,会导致布局错乱;弊端之二:html文件头部需插入一段js代码 )

//设计图px单位 转化为 实机中rem单位公式,如下:iphone6屏幕的宽能装下rem的个数 = 设计图宽度(px) / html根元素的fontsize(px) / 设计图较设备的放大倍数 = 750px / 50px / 2 = 7.5(个) 即:该设计图上E元素的px数据 / 100 = iphone6设备中E元素的rem数据。
 iphone6屏幕的宽能装下rem的个数 = 设计图宽度(px) /  html根元素的fontsize(px) / 设计图较设备的放大倍数
                                                         = 750px / 50px / 2
                                                         = 7.5(个)
即:该设计图上E元素的px数据 / 100 = iphone6设备中E元素的rem数据。

另外,这里介绍一个px自动转rem的 postcss-px2rem插件 ,打包的时候把项目里面的px统一转换成rem,转换的基准值根据配置设置的(postcssrc.js)。

第一步,先用vue-cli快速构建出一个项目,然后,安装postcss,postcss-pxtorem,postcss-loader,postcss-import,postcss-url。

第二步,在项目根目录下添加.postcssrc.js文件,在里面写上:

module.exports = { plugins: { 'postcss-pxtorem': { rootValue: 50, propList: ['*'], minPixelValue: 2 } }};

rootValue,在这里html根元素的字体大小是50px,proplist就是那些属性需要转换成rem,这里是全部的意思;比如你可选择设置; propList: ['font', 'font-size', 'line-height', 'letter-spacing']。minPixelValue就是最小转换单位,这是最小转换单位是2px的意思;
需注意,此插件只负责把项目里面的px按照基准值转换成rem,并不负责根节点动态font-size的计算。

// 动态设置根字体大小!一段简单的js插入在head里面
(function() {
    function autoRootFontSize() {
        // html根元素fontSize大小和屏幕大小成正比
        document.documentElement.style.fontSize = Math.min(screen.width,document.documentElement.getBoundingClientRect().width)  /  750 * 50 + 'px';
    }
    window.addEventListener('resize', autoRootFontSize);
    autoRootFontSize();
})();

 


vw/vh介绍:

viewport即浏览器可视区域大小。
vw:1% of viewport’s width 
vh:1% of viewport’s height 
我们可以这样理解 100vw = window.innerwidth, 100vh = window.innerheight .在移动端我们一般都可以认为,100vw就是屏幕宽度

》》》补充插件 amfe-flexible:自动根据不同设备改变data-dpr的值,这样就可以根据不同的data-dpr设置字体大小不变,仅放大相应倍数。《《《

// 可以用vw去设置根字体大小,html元素fontsize(vw)/设备宽(vw) = 50px/750px = 6.667vw,就不用js去算了!
html{font-size:6.667vw};

接下来,同样可以利用 postcss-px-to-viewport插件 进行px到vw单位的转换。

第一步,先用vue-cli快速构建出一个项目,然后,安装postcss,postcss-px-to-viewport,postcss-loader,postcss-import,postcss-url。

第二步,在项目根目录下添加postcssrc.js文件,在里面写上:

module.exports = { "plugins": {
    "postcss-import": {}, "postcss-url": {}, "postcss-aspect-ratio-mini": {},
    "postcss-write-svg": { utf8: false }, "postcss-cssnext": {}, 
    "postcss-px-to-viewport": { 
        viewportWidth: 750, 
        unitPrecision: 3, 
        viewportUnit: 'vw', 
        selectorBlackList: ['.ignore', '.hairlines'], minPixelValue: 1, mediaQuery: false     
     },             
    "postcss-viewport-units": {}
}}

viewportWidth是你设计稿的大小750,然后unitPrecision是vw值保留的小数点个数。

vw单位 和 %单位 对比:
1、百分比%是根据父元素宽度或者高度进行计算,而vw vh固定按照viewport来计算,不会受父元素宽高度影响。
2、100vw包括了页面滚动条宽度(页面滚动条属于viewport范围内,100vw当然包括了页面滚动条宽度)。但把body或者html设置为width:100%时,是不包括页面滚动条的宽度的。也就是说100vw在有纵向滚动条的情况下,会比100%宽。 那么就会引发一个问题:pc端使用vw单位时,如果有元素width:100vw,而且页面内容又超出一屏长度,出现了纵向滚动条。因为(元素100vw + 纵向滚动条宽度)超出了viewport宽度,则会导致出现横向滚动条。若页面基本上展示在移动端,那么最好用vw/vh(移动端滚动条不占位,所以不会有这个问题)。若还需要兼容pc端还是尽量使用width:100%吧。

 

你可能感兴趣的:(学习经验)