*** 以下均以 2倍于 iphone6/7/8设备尺寸 的设计图(图宽 750px) 为例 ***
*** html根元素fontsize:50px ***
*** E元素(需要转化单位) ***
首先介绍一下2种分辨率的问题???
物理分辨率(基于硬件层,又称 标准分辨率或真实分辨率):显示屏的 最佳分辨率,即屏幕实际存在的像素行数乘以列数的数学表达方式,是显示屏 固有的参数,不能调节,其含义是指显示屏 最高可显示的像素数。
逻辑分辨率(基于系统层,详见1 详见2):是页面上抽象的像素点的多少,其单位为dpi(dot per inch),其大小和UI设计者有关。
两者间由 Scale Factor(缩放因子) 计算得到,通常 物理分辨率 > 逻辑分辨率,而 物理分辨率 = 逻辑分辨率 * 缩放因子;但在使用 台式电脑、和 笔记本 的情况下 物理分辨率 = 逻辑分辨率。
以苹果设备为例:
3.5"、4"等物理尺寸是指屏幕的实际大小。大的屏幕同时必须要配备高物理像素(px)分辨率,也就是在这个尺寸下可以显示多少个像素(px),显示的像素越多,可以表现的余地自然越大。PPI 指 每寸屏幕能容纳多少颗像素,用于描述屏幕的 像素密度。
总结:iphone6/7/8逻辑像素(pt)分辨率为375*667,scale(单位长度 内的(pixel/point)数量比)为@2X。所以要在iphone6/7/8上正常显示,设计稿的物理像素(px)分辨率需要是750*1334.
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数据。
另外,这里介绍一个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();
})();
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%吧。