移动端适配方案

视口介绍

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呢?

方法一: 根据计算转换得到易于计算的比例值

移动端适配方案_第1张图片
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'

参考文章:

https://www.jianshu.com/p/213f98766769

https://www.jianshu.com/p/444b099a5706

你可能感兴趣的:(移动端适配方案)