作者:子非鱼
转发链接:https://mp.weixin.qq.com/s/uQ8c2Z6GJr4eyH3kidZt3g
序言随着Web技能的改造,移动端适配方案也在不断的变革,网上有很多关于移动端适配的文章,说什么rem布局已经由时,vm适配才是最好的适配方案。有这种理解的同学是缺点的,任何适配方案都有它的优缺陷,要结合自己的利用场景来进行选择。
前面
《手把手教你绕过移动端适配大坑》
《吃透移动端 1px|从基本事理到开源办理方案》
《吃透移动端 H5 与 Hybrid|实践踩坑12种问题汇总》
文章先讲一下几种常见的适配方案,然后再看看几个大厂(腾讯、京东、网易、小红书、微博、美团、B站、搜狐、饿了么、携程、大众点评、知乎、拍拍贷、陆金所)的移动端页面都采取了什么样的适配方案,末了谈论下各个适配方法的适用场景和优缺陷,如果有不对之处,希望能得到大佬们的示正。
移动端适配的重新思考
1
移动端适配便是用rem或vw ?并不是所有场景都适宜用用rem或vw进行适配。
vw和rem适配的实质是等比例缩放,让页面在不同屏幕尺寸下有类似于矢量图片缩放的效果,担保了页面元素之间的尺寸缩放比例和位置。这两种适配方案适宜视觉组件种类比较多,视觉设计对元素位置的相对关系依赖较强的移动端页面,基本上大部分页面都可以用这两种方案进行适配。但对付文本内容较多,我们希望勾引用户沉浸在更多的内容而不是更大的内容的,这种等比例缩放的方案并不能知足哀求,我推举直策应用px结合flex等布局办法进行适配。2
rem该抛弃了,利用vw不喷鼻香么 ?vm适配不是万能的,最好与rem合营利用
当初之以是利用rem的方案盛行开来正是由于在那时viewport units的浏览器支持程度不甚空想(IOS 8+, Android 4.4+ 拜会viewport units的caniuse)。而比较较之下rem就好多了(IOS 4.1+, Android 2.1+ 拜会caniuse),以是对付vw,在当时的大环境下前端想说爱你不随意马虎。随着前端技能的改造,最紧张是各大浏览器厂商的给力,除Opera Mini全版本和IE低版本不支持之外,其他的浏览器基本上都已经支持vw了,开始有人或者有团队在磋商论在实际项目中的利用。虽然大漠老师在《再聊移动端页面的适配》一文中提出的vw方案中利用viewport-units-buggyfill库进行兼容的做法,我个人更是不建议,由于这个库利用了css content属性进行兼容处理,官方文档中就指出了对部分浏览器的img标签有影响 ,须要全局引入一条css规则。且对付须要正常利用content的情形(如:图标字体)也会引起不可避免的冲突,其余也不支持伪元素的兼容。以是从我个人的角度来说,如果你一定要问我利用若何的vw适配方案,我会推举给你上述两种vw + rem的方案。虽然采取vw适配后的页面效果很好,但是它是利用视口单位实现的布局,依赖视口大小而自动缩放,无论视口过大还是过小,它也随着视口过大或者过小,失落去了最大最小宽度的限定。移动端适配方案1
rem适配rem适配的实质是布局等比例的缩放,通过动态设置html的font-size来改变rem的大小。
viewport 配置1<!--dpr=1-->2<metaname="viewport"content="width=device-width;initial-scale=1;maximum-scale=1;minimum-scale=1;user-scalable=no;">
上面把scale设置成固定1倍的视口的大小,也可以根据dpr的值缩放viewport,如下:
1//下面是根据设备dpr设置viewport 2vardpr=window.devicePixelRatio||1 3varscale=1/dpr 4 5viewport.setAttribute( 6"content", 7"width=device-width"+ 8",initial-scale="+ 9scale+10",maximum-scale="+11scale+12",minimum-scale="+13scale+14",user-scalable=no"15)
有几点要把稳
viewport标签只对移动端浏览器有效,对PC端浏览器是无效的。当缩放比例为100%时,逻辑像素 = CSS 像素宽度 = 空想视口的宽度 = 布局视口的宽度。单独设置initial-scale或 width都会有兼容性问题,以是设置布局视口为空想视口的最佳方法是同时设置这两个属性。纵然设置了user-scalable = no,在Android Chrome浏览器中也可以逼迫启用手动缩放。设置 rem 基准值核心代码为如下
1//set1rem=逻辑像素(设备独立像素)/102functionsetRemUnit(){3varrem=document.documentElement.clientWidth/104//375/10=37.55docEl.style.fontSize=rem+'px'6}7setRemUnit()
1module.exports={ 2plugins:{ 3'autoprefixer':{ 4browsers:['Android>=4.0','iOS>=7'] 5}, 6'postcss-pxtorem':{ 7rootValue:37.5, 8propList:['','!font-size'], 9selectorBlackList:['van-circle__layer','ignore'],10}11}12}
在相应式布局中,必须通过js来动态掌握根元素font-size的大小,也便是说css样式和js代码有一定的耦合性,且必须将改变font-size的代码放在css样式之前。
2
vw适配
vw是基于Viewport视窗的长度单位,这里的视窗(Viewport)指的便是浏览器可视化的区域,而这个可视区域是window.innerWidth/window.innerHeight的大小,用图大略的示意如下
在CSS Values and Units Module Level 3中和Viewport干系的单位有四个,分别为vw、vh、vmin和vmax。
vw:是Viewport's width的简写,1vw即是window.innerWidth的1%vh:和vw类似,是Viewport's height的简写,1vh即是window.innerHeihgt的1%vmin:vmin的值是当前vw和vh中较小的值vmax:vmax的值是当前vw和vh中较大的值如果设计稿利用750px宽度,则100vw = 750px,即1vw = 7.5px。那么我们可以根据设计图上的px值直接转换成对应的vw值。如果不想自己打算,我们可以利用PostCSS的插件postcss-px-to-viewport,让我们可以直接在代码中写px。
1{ 2loader:'postcss-loader', 3options:{ 4plugins:()=>[ 5require('autoprefixer')({ 6browsers:['last5versions'] 7}), 8require('postcss-px-to-viewport')({ 9viewportWidth:375,//视口宽度(数字)10viewportHeight:1334,//视口高度(数字)11unitPrecision:3,//设置的保留小数位数(数字)12viewportUnit:'vw',//设置要转换的单位(字符串)13selectorBlackList:['.ignore','.hairlines'],//不须要进行转换的类名(数组)14minPixelValue:1,//设置要更换的最小像素值(数字)15mediaQuery:false//许可在媒体查询中转换px(true/false)16})17]18}
3
搭配vw和rem
给根元素大小设置随着视口变革而变革的vw单位,这样就可以实现动态改变其大小。限定根元素字体大小的最大最小值,合营body加上最大宽度和最小宽度。 1// rem 单位换算:定为 75px 只是方便运算,750px-75px、640-64px、1080px-108px,如此类推 2$vm_fontsize:75;//iPhone6尺寸的根元素大小基准值 3@functionrem($px){ 4@return($px/$vm_fontsize)1rem; 5} 6//根元素大小利用vw单位 7$vm_design:750; 8html{ 9font-size:($vm_fontsize/($vm_design/2))100vw;10//同时,通过MediaQueries限定根元素最大最小值11@mediascreenand(max-width:320px){12font-size:64px;13}14@mediascreenand(min-width:540px){15font-size:108px;16}17}18//body也增加最大最小宽度限定,避免默认100%宽度的block元素跟随body而过大过小19body{20max-width:540px;21min-width:320px;22}
4
px 适配
就像开篇提到的,并不是说移动端就一定要利用相对长度单位,传统的相应式布局依然是很好的选择,尤其在新闻,社区等可阅读内容较多的场景直策应用px单位可以营造更好地体验。px方案可以让大屏幕手机展示出更多的内容,更符合人们的阅读习气。
互联网大厂的适配调研
1
rem适配例子
1.1 固定1倍vieport注:下面描述的rem与px的对应关系是在设备独立像素为375px(iPhone6/7/8)情形下。
拍拍贷m站首页(https://m.ppdai.com/)
1rem = 20px最大基准值为40px限定页面宽度750px小红书(https://www.xiaohongshu.com/)
1rem = 50px最大基准值为60px字体和页面都进行缩放合营media query,限定body的最大宽度1@mediascreenand(min-width:768px)2body{3width:450PX!important;4}
微博(https://m.weibo.cn/)
字体和页面都进行缩放基准值是根据media query天生的1.2 可缩放vieport下面描述的rem与px的对应关系是在设备独立像素为375px(iPhone6/7/8)、viewport scale 0.5的情形下。
美团(http://i.meituan.com/)
1rem = 100pxB站主站(https://m.bilibili.com/index.html)
1rem = 46.875px搜狐(https://m.sohu.com/)
1rem = 75px2
vm适配例子拍拍贷借款页(https://ld.ppdai.com/loan/mobile_base/373/25999?)
不限定页面宽度无兼容性处理,个人不推举3
vm+rem适配例子京东(https://m.jd.com/)
固定vieport,元素布局上利用rem单位html元素的font-size利用vw + px fallback的形式当页面超过一定宽度时,根据media query设置font-size为px,优先级高于vw。限定页面宽度为1080pximage.png
网易(https://3g.163.com/touch/)固定viewport,元素布局上利用rem单位html元素的font-size利用vw + px fallback的形式利用media query设置根元素font-size中px的值当页面超过一定宽度时,px单位的优先级高于vw限定布局宽度为768px
饿了么(https://h5.ele.me/msite/)对viewport进行了缩放html元素的font-size依然由px指定详细元素的布局上利用vw + rem fallbak的形式没有限定布局宽度css构建过程须要插件支持,可参考这个插件:pandaGao/stylus-px-to-relative-unit4
px 方案例子携程(https://m.ctrip.com/html5/)
固定1倍vieport布局方案:px+flex+百分比设置body的最大宽度为max-width: 540px;大众点评(https://m.dianping.com/)
元素较丰富,采取px+flex布局,适配效果很好知乎(https://www.zhihu.com/)
追求阅读体验的场景,利用px布局。腾讯(https://xw.qq.com/)
首页紧张内容是新闻,为了更好的阅读体验,利用px布局。陆金所(https://m.lu.com/)
:root {font-size:10px;},并没有根据屏幕的大小来设置不同的font-size存在问题:布局页面设成1rem时候,在chrome浏览器上任然12px,并不是10px布局中虽然用了rem单位,但实在还是绝对单位方案可能希望用户在大屏手机上能看到更多内容吧总结新闻,社区等可阅读内容较多的场景:px+flex+百分比对视觉组件种类较多,视觉设计对元素位置的相对关系依赖较强的移动端页面:vw + rem以上只是自己的鄙见以及自己这一两年有关于移动端适配的一些探索,如果有不对之处,还请各路大神示正。
作者:子非鱼
转发链接:https://mp.weixin.qq.com/s/uQ8c2Z6GJr4eyH3kidZt3g