1. 什么是前端适配

从UI展现层面上:

我们期望不同尺寸的设备,页面可以自适应的展示或者进行等比缩放,从而在不同的尺寸的设备下看起来协调或者差不多。

从代码实现层面上:

我们希望前端适配可以用用尽可能简洁的代码来实现。最好一套代码实现兼容所有设备,而不是对每个或每种设备都写一套方案,不是次次都选用最无奈的方案(Android和iOS分开编写)。

2. 关键字

如果你了解这些关键字,那么这段大可以跳过,如果后面遇到了问题,感觉有些疑惑,也可以再回来查阅。

2.1 Viewport/视口


通俗的讲,移动设备上的viewport就是设备的屏幕上能用来显示我们的网页的那一块区域[1],但不一定是我们可见的区域。具体来说,分为以下三种。

2.1.1 Visual Viewport

Visual Viewport: 可见视口。就是移动设备上可以被我们看见的部分。宽度在移动端通过window.innerWidth获得(仅限移动端,PC上哪怕是chrome模拟也会有不同的结果)。

2.2.2 Layout Viewport

Layout Viewport: 布局视口。

如果把PC上的页面放到移动端,以iphone8为例,如果只展示为可见视口的宽度(375px),那么页面会被压缩的特别窄而显示错乱,所以移动浏览器就决定默认情况下把viewport设为一个较宽的值,比如980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。[1]

而事实上,我们一般看不到如上图这样出现横向滚动条的界面;在手机上访问页面时,往往是下图的样子:

这是由于页面body宽度设置了100%而没有指定一个具体的宽度导致的,从而使页面被等比缩放了。由于用户可以缩放,所以还算能正常浏览。

2.2.3 Ideal Viewport

Ideal Viewport:理想视口,其实就是设备的可见区域,和可见视口一致。

设置Ideal Viewport的好处是,只要按照Ideal Viewport来设计样式稿,用户就不用能最完美的查看网站的内容——既不用左右滑动,也不用放大缩小。

设置理想视口:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/>

这段代码的意思是将布局视口的宽度设置为设备宽度,初始缩放比例为1,最大缩放比例为1,用户不能缩放。

2.2 像素

2.2.1 物理像素

物理像素:一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。[2]

2.2.2 设备独立像素

设备独立像素:又称为CSS像素,就是我们日常代码中使用的像素。浏览器内的一切长度都是以CSS像素为单位的,CSS像素的单位是px。

2.2.3 设备像素比

设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系。比如说对于iOS的retina屏,一个设备独立像素就对应着4个物理像素。这样的设计可以使画面更加清晰锐利,如下图:

3. 业界的解决方案

OK,LongLongAgo的前缀之后,终于到了正题。回到我们最开始的初心:我们只是想要通过一套代码,实现一个可以在不同页面尺寸上展示差不多的页面。在这一块,现在主要有三种方案。

3.1 Rem的解决方案

DPR一致时,px在不同的屏幕尺寸上会展示为定宽,这就导致我们的页面可能会出现滚动条或者占不满的情况。而通过rem来设置div的宽高,可以保证页面可以通过调整html的font-size来整体放大或者缩小,从而达到不管屏幕宽度是多少,页面都能完美展示的效果。

例如,针对750*1334的设计稿:

<meta name="viewport" content="initial-scale=1,maximum-scale=1, minimum-scale=1">

<script>

document.documentElement.style.fontSize = window.innerWidth / 7.5 + 'px';

</script>

这样,所有的设备的宽度都是7.5rem,只需要把设计稿上的px值统一除以100,就可以得到相应的rem值了。

网易也采用的这种方法。

3.2 Flexible.js

Flexible是阿里团队开发的前端适配方案,也是用的rem的方法。那么第一种方法其实已经能解决前端适配问题了,为什么阿里还要开发一个Flexible呢?

在第一种方法中,dpr=1时没有任何问题,但是在dpr=2或者更高的手机屏幕上,因为物理像素的增加,存在小于1px的显示空间。如果采用第一种方法,因为它统一对scale设置为1,那么我们假如想要实现0.5px, 就只能通过transform的方式。如果有多个这样的样式,代码就会变得很麻烦。

.scale{

position: relative;

}

.scale:after{

content:"";

position: absolute;

bottom:0px;

left:0px;

right:0px;

border-bottom:1px solid #ddd;

-webkit-transform:scaleY(.5);

-webkit-transform-origin:0 0;

}

因此,阿里的flexible方案充分考虑了这种情况,动态的设置了fontsize和scale, 从而使得CSS中的1px等于物理像素中的1px,在IOS下得到最清晰的体验。

if (!dpr && !scale) {

var isAndroid = win.navigator.appVersion.match(/android/gi);

var isIPhone = win.navigator.appVersion.match(/iphone/gi);

var devicePixelRatio = win.devicePixelRatio;

if (isIPhone) {

// iOS下,对于2和3的屏,用2倍的方案,其余的用1倍方案

if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {

dpr = 3;

} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)){

dpr = 2;

} else {

dpr = 1;

}

} else {

// 其他设备下,仍旧使用1倍的方案

dpr = 1;

}

scale = 1 / dpr;

}

最终在iphone8下页面的header被设置为:

<meta name="viewport" content="initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no">

具体的大家可以看《使用Flexible实现手淘H5页面的终端适配》

另外需要指出的一点是:Flexible将页面分成了100份,页面的宽度是10rem,对于750的设计稿,我们需要用相应的px数除以75来得到。手动计算是愚蠢的,不同的编译器都可以下载pix2rem插件(可以直接写px然后自动转换为相应的rem值),直接使用sass或者postcss打包也能达到同样的功能。

总结一下上面两种rem方法,主要思想为:

  • 根据dpr的值来修改html的font-size,从而使用rem实现等比缩放

  • 根据dpr的值来修改viewport实现1px的线

但是Flexible也有它的局限性,具体表现为:

  • 不能与响应式布局兼容

  • 对Android没有做处理,导致1px和backgroudImage还要额外做处理的问题[4]

所以我们有了第三种解决方案——vw。

3.3 vw

vw是基于Viewport视窗的长度单位,在CSS3中和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中较大的值

其实vw的方案的写法和flexible方案的写法一致——因为flexible其实就是用hack的手段模拟了vw的实现而已。

具体写法:针对750px的设计稿,将相应的px值除以75就是vw的值。

因为此方法不会改变可见视口的宽度,所以可以和media query通用了,另外,也支持了Android上高分辨率屏的展示。

尽管在某些Android机型上还存在兼容问题,我们也可以使用Viewport Units Buggyfill,具体见《如何在Vue项目中使用vw实现移动端适配》

总结

正如大漠所说,flexible模拟vw的时代已经过去,真正的酋长vw已经归来。

原文发布时间为:2018-10-09
本文作者:tomc
本文来自云栖社区合作伙伴“编程微刊”,了解相关信息可以关注“编程微刊”。

茴字的四种写法——浅谈移动前端适配相关推荐

  1. 茴字的四种写法—移动适配方案的进化

    话说我刚工作的时候,就开始用rem了,过了没多久,接触到了flexible,系统化且支持iOS的retina屏迅速征服了我,最近又看到了大漠大神的vw.所以本文想完成一篇一站式的文章,可以系统的了解前 ...

  2. “茴”字有四种写法,this也是一样

    说到这个地方又想起以前高中还是初中学的<孔乙己>这个梗,但是这里的this显然实用性比那个要大很多,哈哈. 简单来说,this有四种应用场景,分别是在构造函数上.对象属性中.普通函数中.c ...

  3. 编程代码风格之茴字有四种写法

    (养成中午写blog的习惯) 一直以来注意代码风格. 最早的时候使用Visual Basic时,没有花括号{},也不需要;,靠换行和缩进来控制逻辑,遇到复杂的事情时候很着急,及至后来开始深入到C, J ...

  4. 回字有四种写法,阶乘verilog实现有几种方法?

    回字有四种写法,阶乘verilog实现有几种方法? 方式一:普通方式实现阶乘计算: verilog代码: module tryfact; function[31:0]factorial; input[ ...

  5. android应用前端,Android应用开发之浅谈移动前端适配

    本文将带你了解Android应用开发之浅谈移动前端适配,希望本文对大家学Android有所帮助 1. 什么是前端适配 从UI展现层面上: 我们期望不同尺寸的设备,页面可以自适应的展示或者进行等比缩放, ...

  6. 回字有四种写法,那你知道单例有五种写法吗

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达今日推荐:2020年7月程序员工资统计,平均14357元,又跌了,扎心个人原创100W+访问量博客:点击前往,查看更多 转自 ...

  7. 【转】回字有四种写法,那你知道单例有五种写法吗

    目录导航 基本介绍 写法介绍 饿汉式 懒汉式 双重检测 内部类 枚举 总结 基本介绍 单例模式(Singleton)应该是大家接触的第一个设计模式,其写法相较于其他的设计模式来说并不复杂,核心理念也非 ...

  8. 单例模式( Single Pattern ): 不仅仅是回字的四种写法

    单例模式作为入门编程人员面试必考题之一,也是被玩坏了, 猛然一搜尽然有七种写法,什么懒汉,饿汉五花八门, 这里参考已经比较不错的文章, 忽略五花八门的命名, 把单例模式不同写法按逻辑演进梳理一下, 方 ...

  9. python:函数中五花八门的参数形式(茴香豆的『回』字有四种写法)

    毫不夸张的说,python语言中关于函数参数的使用,是我见过最为灵活的,随便怎么玩都可以,本文以数学乘法为例,演示几种不同的传参形式: 一.默认参数 def multiply1(x, y):retur ...

最新文章

  1. Exp2 后门原理与实践 20164323段钊阳
  2. 动态添加控件及将某XML动态加入到Activity显示
  3. SpringBoot用Servlet处理请求
  4. Oracle中Cursor介绍
  5. 什么是SAP OData Model Creator
  6. IOC操作Bean管理注解方式(组件扫描配置)
  7. 梯度消失和梯度爆炸_梯度消失梯度爆炸-Gradient Clip
  8. nacos 下线接口_微服务架构nacos注册中心为什么那么火
  9. C++ 从入门到入土(English Version)Section 9 : Computer Graphics and Command Prompt
  10. 多重继承有时候确实有必要
  11. 利用WireShark破解网站密码
  12. 「Head First」编程系列丛书
  13. table表格头部和前几列固定js
  14. (转)《蜗居》带给校园男女多少悲喜
  15. Android Jetpack组件之Room数据库使用
  16. 人脸脸部识别技术_面部识别技术基础
  17. 基于搜索的贝叶斯网络结构学习算法-K2
  18. 多变量干扰事件发生下的地铁客流预测
  19. android 图片叠加xml,Drawable子类之——LayerDrawable (图层叠加)
  20. root用户执行sourc /etc/profile命令提示权限不够

热门文章

  1. 【WSL】配置zsh
  2. 操作系统发展历程 (Unix、Linux、windows)
  3. SOCKS5实现代理服务器(C++)
  4. ORA-28002: the password will expire within 2 days
  5. java excel 多列排序,《excel表格调取行和列的数据》 excel列排序的时候怎么让所有行的信息跟着排(其它的非数据行)...
  6. 练手小项目——canvas放大镜效果 放大图片
  7. linux下打开chm格式文件
  8. 危化企业如何建设人员定位、智能巡检等安全管理平台
  9. 一.僵死进程(僵尸进程)
  10. 基于VOIP的SIP协议分析