视口介绍
1、布局视口(layout viewpor)
var width=document.documentElement.clientWidth
可以看作为当前顶级HTML元素的宽度,也就是咱们浏览器当前的可视区域的宽度,咱们的媒体查询max-width和min-width的值也是布局视口的宽度,布局视口中的宽度和高度都是像素,也就是px,是一个抽象单位。 布局视口宽度受到meta标签内的width属性和initial-scale的影响,仅设置width的值时,这个值就是布局视口的宽度,它的值可以是正整数或者特殊值device-width。 布局视口宽 = 可视视口宽时html 元素正好横向铺满窗口(但其后代元素若有横向 overflow 的情况,仍然会出现滚动条),布局视口宽 > 可视视口宽时,出现横向滚动条。
2 : 可视视口(visual viewport)
var width=window.innerWidth
可视视口是当前可见区域的CSS像素数,和布局视口差不多,区别可视视口的宽度决定了将页面分成了多少份,每份对应一个CSS像素。可视视口受到缩放比例的影响,在meta标签内设置了initial-scale=0.5 后会改变可视视口的尺寸,可视视口尺寸越小显示的CSS像素数也越少,则单位CSS像素数对应的可视区域越大,对应的缩放比例也就越大。缩放比例是相对于理想视口而言缩放比例 = 理想视口尺寸/可是视口尺寸,而当没有设置initial-scale的时候,浏览器会取适当的缩放比例,一般情况下为1,使布局正好铺满屏幕,此时布局视口尺寸 = 可视视口尺寸。
3 : 理想视口(ideal viewport)
var width=screen.width
理想视口是一个比较适合移动布局的视口尺寸,作为计算布局视口和可视视口尺寸的基准值,上面mete标签中的device-width 就是理想视口的宽度。上面三个视口属性中,只有理想视口是不可以改变的,因为理想视口的宽度拒绝与设备的物理像素比存在着比例的关系,这个比例叫做设备像素比(device pixel ratio,dpr)。
公式为 :设备像素比 = 物理像素数 / 理想视口尺寸。
iPhone 物理宽度像素 640 理想视口宽度 320 设备像素比 2
var c=window.devicePixelRatio 这样可以获取设备像素比(Android系统下可能不符合预期),由于没有禁用缩放属性,手动缩放不会影响布局视口或者理想视口,只会影响到可视视口的尺寸,而且可能导致布局视口小于理想视口。设置 initial-scale 的值时,布局视口的尺寸与可视视口的计算方式相同,但不受手动缩放的影响同时设置 width 和 intial-scale 的值时,布局视口的宽取上述两个值中较大的一个。
总结
1 : 将meta标签中的width设为device-width时,布局视口 = 可视视口 = 理想视口,这时设备像素比,设备像素比 = 物理像素 / 理想视口尺寸 = 物理像素比 / 布局视口尺寸,对iphone而言,一个CSS像素对应4个物理像素。
2 : initial-scale 设置任意合法的值同时禁用手动缩放时,布局视口 = 可视视口。
3 : initial-scale 设置为1时也可以使布局视口 = 可视视口 =理想视口。
flexible的适配方案
flexible方案会把视觉稿分为100份,主要是为了更好的兼容vh 和 vw ,而每一份被称为一个单位a,同时1rem单位被认定为10a。假设设计稿是750px规格,1a = 750px/100,1rem = 10a = 75px,所以根元素相对应的font-size=75px。
但在开发过程中我们怎么将设计稿的px转换成相对单位的rem呢?
方法一: 根据计算转换得到易于计算的比例值
刚才我们计算了设计稿1rem = 750px/10 = 75px , 实际屏幕1rem = clientWidth / 10; 根据比例得到 1rem = 75px = clientWidth/10 ,我们发现根据上图公式Math.floor(100 * (clientWidth / 750))发现右边除以750在乘1000(为什么要成1000呢,为了减小计算误差咯),所以左边也除以750在乘1000,可以得到 1rem = 100px; 现在设计稿有段长度是240px,口算得到相对单位2.4rem
方法二:根据css预编译sass或less的函数来计算rem值
根据设计稿得到1rem = 75px; 编写scss文件
// rem.scss
$baseUnit = 75px;
@function pxToRem($px){
@return $px / $baseUnit + 'rem'
}
// 如何使用
@import 'rem.scss'
div {
height: pxToRem(200)
}
方法三:借助插件自动计算:px2rem,postcss-pxtorem等,请自行选择,这里介绍在Vue中使用px2rem。
1 、npm install px2rem-loader
2、在vue-cli 项目中build下的 utils.js中,找到generateLoaders 方法修改配置
var px2remLoader={
loader:'px2rem-loader',
options:{
remUnit:75 // 设计稿宽度/10
}};
// generate loader string to be used with extract text plugin
function generateLoaders(loader,loaderOptions){
var loaders=[cssLoader,px2remLoader];//添加px2rem 插件
if(loader){
loaders.push({
loader:loader+'-loader',
options:Object.assign({},loaderOptions,{sourceMap:options.sourceMap})
})
}
3、vue-cli3.0中需要在vue.config.js中配置 chainWebpack
chainWebpack: config=> {
config.module
.rule('scss')
.oneOf('vue')
.use('px2rem-loader')
.loader('px2rem-loader')
.before('postcss-loader') // this makes it work.
.options({remUnit:75})
.end()
}
现在就可以在项目中愉快的使用px了,设计稿是多少,就写多少,自动转换成rem,不要太爽
注意:这里是通过自定义函数来设置根元素html的字体大小(即rem),我们可以使用淘宝的库lib-flexible,这个库会自动计算设置根元素html的字体大小
npm install lib-flexible -save 然后在main.js 中引入这个文件
// main.js
import 'lib-flexible/flexible'
参考文章: