[月分享] 我对移动端适配的了解

不知不觉做前端已经两年了,从PC端,移动端,微信小程序一路走来到今天刚刚开放注册的快应用(手机厂商对抗小程序的新技能,所以在注册时用的是qq邮箱的话要去垃圾箱里才能找到注册邮件),对于前端圈日新月异的磅礴发展对于大前端发展是喜闻乐见的,这次的快应用的手机厂商们为其开放了应用入口和系统推广引流入口。这些新能力为前端开发者们带来更强的作战能力。

我们在开发PC站时经常在浏览器兼容问题上耗费巨大的时间,到了移动端,面对webkit内核的Safari与Chrome会舒心很多。but,我们要对于市面上的手机各式各样的分辨率进行适配,刚接触移动端开发的时候是不是有点猝不及防哈哈,尤其是去年年中以前老版本的微信内置浏览器用的X5内核,给网友们戏称移动端IE...


2.png

今天的主题是讲的是我对移动端多终端适配的解决方案和移动端适配的有关布局的知识总结,下面正式开始。

基本概念和原理

首先要了解的重要的基础知识点:物理像素,设备独立像素,css像素 ,设备像素比,布局视口,可视视口 , 理想视口以及css单位rem。

物理像素(设备像素)
屏幕的物理像素,又被称为设备像素。任何设备屏幕的物理像素出厂时就确定了,是固定不变的。
设备独立像素
设备独立像素也可以理解为CSS像素,可以认为是计算机坐标系统中的一个点,这个点代表一个可以由程序使用的虚拟像素(比如说CSS像素)。
设备像素比
设备像素比简称为dpr,dpr = 物理像素 / 设备独立像素。(以iphone6为例: dpr = 750 / 375 , 所以它的像素密度比为2,即 1个CSS像素 跨越了 2个物理像素),我们可以通过 window.devicePixelRatio 来获取设备的像素密度,像素密度大于1就是高清屏。
CSS像素
在CSS、JS中使用的一个长度单位,单位px。
注:在pc端1物理像素等于1px,但是移动端1物理像素不一定等于1px(高清屏)。

布局视口(layout viewport)
可以看作是html元素的上一级容器即顶级容器,默认情况或者将html元素的width属性设为100%时,会占满这个顶级容器,此时用 document.documentElement.clientWidth 获取到html元素的布局宽度也就是布局视口的宽度,使用媒体查询时 max-width 和 min-width 的值指的也是布局视口的宽。
在html中一般在meta中的name为viewport字段就是控制的布局视口。布局视口一般都是浏览器厂商给的一个值。在手机互联网没有普及前,网络上绝大部分页面都是为电脑端浏览而做的,根本没有做移动端的适配。
随着移动端的发展,在手机上看电脑端的页面已成为非常普及现象。而电脑端页面宽度较大,移动端宽度有限,要想看到整个网页,会有很长的滚动条,看起来非常麻烦。于是浏览器厂商为了让用户在小屏幕下网页也能够显示地很好,所以把布局视口设置的很大,一般在768px ~ 1024px 之间,最常用的宽度就是 980。
这样用户就能看到绝大部分内容,并根据具体内容选择缩放。
故布局视口是看不见的,浏览器厂商设置的一个固定值,如980px,并将980px的内容缩放到手机屏内。一块手机屏幕,物理像素的数量是固定不变的。
视觉视口的大小是继承自布局视口的大小,视觉视口和布局视口的宽度为CSS的px数(可变的)。

理想视口
布局视口虽然解决了移动端查看pc端网页的问题,但是完全忽略了手机本身的尺寸。所以苹果引入了理想视口,它对设备来说是最理想的布局视口,用户不需要对页面进行缩放就能完美的显示整个页面。最简单的做法就是使布局视口宽度设置为手机屏幕的宽度。移动端到底怎么适配不同的屏幕呢?最简单的方法是设置如下视口:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
复习一下: dpr = 物理像素 / 设备独立像素。
以iphone6为例,iphone6的物理像素为750,如果没有设置布局视口时,布局视口viewport默认为980px
此时:dpr = 750 / 980 = 0.76531,等于1个CSS像素有0.76531个物理像素。接近于1像素密度所以pc端的页面在手机端看时不会太小。
当在meta中设置了如下配置时:
<meta name="viewport" content="width=device-width">
相当于把布局视口设置为设备的宽度(即设备独立像素),
iphone6的设备独立像素为 375px。
此时:dpr = 750 / 375 = 2,等于1个CSS像素有2个物理像素。此时把pc端的尺寸拿来手机端看时字体和元素会特别大只。

现在移动端设计稿都是基于iphone设计的,一般为750px或640px,对应的是iphone6和iphone5的物理像素。在设计稿中,1px像素边框对应的是1物理像素。而在iphone5和iphone6中,当布局视口width=device-width时,css的1px显示出来的是2个物理像素,所以用户看到的是2px的边框。怎么解决呢?1px边框效果其实有很多hack方法,其中一种就是通过缩放viewport。
<meta name="viewport" content="width=device-width,initial-scale=0.5, maximum-scale=0.5, minimum-scale=0.5, user-scalable=no">
viewport缩放
initial-scale是对布局视口进行缩放,initial-scale是相对于理想视口的,即initial-scale=1与width=device-width是一样的效果。initial-scale=0.5等效于width= 2倍的 device-width,所以设置initial-scale和width都可以改变布局视口的大小。
对于可视视口的缩放可以理解为,用户用双指对页面进行缩放,当用户缩小页面时,可视视口变大用户可以看到的东西越多,当用户放大页面时,可视视口
变小,用户看到的东西越少。
对于iphone6当添加如上设置后,initial-scale=0.5时。
布局视口: 375px * 2 = 750px;
所以此时布局视口为750px,此时1px等于1物理像素了。(移动端一像素有很多hack写法比如用伪类实现,svg实现等等)
看到这是不是觉得要消化的知识点有点多,不怕,休息一下消化消化,每个人都是这样过来的。猥琐发育~

多种适配方案探究

当设计师给出ui图时,面对市场上各式各样的手机它们屏幕大小不同,dpr不同,屏幕尺寸也是各种大小,那么我们应该怎么做到对ui设计图的充分还原,使得项目在各式各样的手机里运行呢?为了解决这种情况出现了许多的适配方案,各方案的实现方法不一样,还原程度也不一样,下面来总结一下常见的几种适配方案及其原理。
方案一:固定高度,使其宽度自适应
这也是我接触移动端适配第一次使用的方案。
这个方案使用了理想视口,使得布局视口等于设备宽度。
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
在布局方面纵向使用固定px值,横向使用自适应布局(百分比,felx,小额定值)。
这种方案相对简单,ui还原度比较低。

方案二:固定布局视口宽度,使用viewport进行缩放(网易、荔枝FM)


       if(/Android (\d+\.\d+)/.test(navigator.userAgent)){
           var version = parseFloat(RegExp.$1);
           if(version>2.3){
               var phoneScale = parseInt(window.screen.width)/640;
               if(/MZ-M571C/.test(navigator.userAgent)){
                   document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
               }else if(/M571C/.test(navigator.userAgent)&&/LizhiFM/.test(navigator.userAgent)){
                   document.write('<meta name="viewport" content="width=640, minimum-scale = 0.5, maximum-scale= 0.5">');
               }else{
                   document.write('<meta name="viewport" content="width=640, minimum-scale = '+ phoneScale +', maximum-scale = '+ phoneScale +', target-densitydpi=device-dpi">');
               }
           }else{
               document.write('<meta name="viewport" content="width=640, target-densitydpi=device-dpi">');
           }
       }else{
           document.write('<meta name="viewport" content="width=640, user-scalable=no, target-densitydpi=device-dpi">');
       }

固定布局视口,宽度设置固定的值,总宽度为640px,根据屏幕宽度动态生成viewport。(设计稿宽度为640px)
这种布局方案页面宽度始终为640px通过设置缩放比例scale实现适配:
var scale = window.screen.width / 640;
当设计稿为640px时,我们可以直接用1:1px来写像素单位。这种布局方案中的1px不一定等于1px,当设备为iphone6时
1px(css) = window.screen.width*dpr = 640 = 375 * 2 / 640 = 1.171875(设备物理像素)
荔枝FM这种适配方案用到了target-densitydpi , 这是一个将被抛弃的属性,因此不推荐使用这套方案(学习一下思路也不错)

方案三:根据不同屏幕动态写入font-size,以rem作为宽度单位,固定布局视口。(网易新闻)
首先设置理想视口:
<meta name="viewport" content="width=device-width,initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
接下来计算 html 元素的 font-size,将可视视口的宽度乘以一个系数:

理论上这个系数可以是任意值,假设将这个系数取 1,则 html 元素的 font-size 即1 rem等于可视视口的宽度,此时以 rem 为单位的长度 n rem 就可以理解为 n 倍可视视口的长,这个系数取 0.01 时,1 rem 等于可视视口宽的 1/100,也就等于布局视口宽的 1/100,也就等于 1vw。实际使用过程中这个系数的选择尽可能方便将设计稿长度数值换算为css中的长度数值
网易新闻手机网易网选择的系数为 100 / 750,这个系数可以如下推出:

750px 是设计稿的宽度(以iphone6的物理像素数为标准),100是期望的换算比例,即设计稿中 100px 的长度对应css中 1rem,将设计稿中的长度数值除以 100 得到的就是以 rem 为单位的 css 长度的数值,设计稿的宽换算为以 rem 为单位的 css 长度应为 (750/100) rem,同时设计稿的宽对应可视视口的宽,即有 (750/100) rem = 可视视口宽,1 rem = 可视视口宽 * (100/750),(100/750)就是我们要的系数
在页面初始化时设置一下 html 元素的 font-size:

在750宽的设计稿:document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
在640宽的设计稿:document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';
这套方案能百分比还原设计稿。

方案四:根据不同屏幕动态写入font-size和viewport,以rem作为宽度单位.
将屏幕分为固定的块数10:

var width = document.documentElement.clientWidth; // 屏幕的布局视口宽度
var rem = width / 10; // 将布局视口分为10份
这样在任何屏幕下,总长度都为10rem。1rem对应的值也不固定,与屏幕的布局视口宽度有关。

动态缩放view:

var devicePixelRatio = window.devicePixelRatio;
var isIPhone = window.navigator.appVersion.match(/iphone/gi);
var dpr,scale;
if (isIPhone) {
  if (devicePixelRatio >=3) {
    dpr = 3;
  } else if (devicePixelRatio >=2) {
    dpr = 2;
  } else {
    dpr = 1;
  }
} else {
  dpr = 1;
}
scale = 1 / dpr;

淘宝只对iphone做了缩放处理,对于android所有dpr=1,scale=1即没有缩放处理。

此方案与方案三相似,增进了viewport缩放使得在iphone上1px(css) = 1px(物理像素),这套方案能百分比还原设计稿。
Flexible实现手淘H5页面的终端适配
方案五:
可以来看看我总结的 : 大漠老师最新的vw移动端适配方案


最后看到这里相信大家心里都有个底,知道选择哪一种方案更能适配自己所开发的项目

(~ ̄▽ ̄)~

see u ~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,088评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,715评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,361评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,099评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,987评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,063评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,486评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,175评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,440评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,518评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,305评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,190评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,550评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,152评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,451评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,637评论 2 335

推荐阅读更多精彩内容

  • 一、meta标签的效果 移动端页面一般会在head头部添加如下meta标签。 该meta标签是否添加对页面渲染的影...
    nimw阅读 3,504评论 0 5
  • 在移动互联网快速发展的今天,手机的种类和尺寸越来越多,作为前端的小伙伴们可能会越来越头疼,但又不得不去适配一款又一...
    keenjaan阅读 26,741评论 9 86
  • title: 移动端Web页面适配浅析date: 2018-01-31 16:38:01tags: 移动端 适配 ...
    豆板儿阅读 12,232评论 0 16
  • 我们第一次接触移动web的时候,直观印象样应该是:屏幕比pc小很多,所以对pc端设计的界面,不一定(或者说不完全)...
    Scaukk阅读 16,797评论 6 46
  • 唯独今夜, 我在月光下等待。 城市的其它人都走了, 只剩下你和我, 我看着你,我想你; 无论向前还是向后, 你都离...
    广厦阅读 198评论 4 0