说起移动端页面也是老生常谈了,最近正好在做金融商城移动端的开发,正好梳理下这一块的知识点,提炼和总结。
一 什么是移动端页面
首先
不扯那些长篇大论,常见的移动端页面主要就三种,即H5页面、手机页面、以及webview页面。
移动端的兴起,访问的流量很大一部分都来自于手机,而通常当手机访问页面的时候,每台设备的分辨率、型号、屏幕尺寸都不一致,导致移动端的兼容适配成为一个很难忽视的问题。
为了让设计稿在大部分设备上都能有相对满意的效果,尤其是在移动端,显然在pc端的px计算像素的方式已经不适用。
二 几个名词
1 viewport
现在开发的页面主要集中在H5页面这个方向,而说到移动端页面,就必须要提到viewport.
先说用到哪,再说是什么、为什么这么用。
随便打开一个线上的H5的页面,你都会在head里发现这个标签<meata name="viewport" content="initial-scale=..., maximun-sacle=..., minimun-scale=..., user-scalable=no">
金融商城H5端
淘宝移动端
所有的移动端页面都用到了这个属性,那么这个属性的定义是什么?
我们知道手机的分辨率各有各的不同,很难做到一套代码,所有的机型都适配,再加上一些历史的原因,浏览器对移动端的属性支持力度不同。所以需要一个折中的方法做到绝大多数设备都能适用。
2. 物理像素(physical pixel)
一个物理像素是显示器(手机屏幕)上最小的物理显示单元,在操作系统的调度下,每一个设备像素都有自己的颜色值和亮度值。
3. 设备独立像素(density-independent pixel)
设备独立像素(也叫密度无关像素),可以认为是计算机坐标系统中得一个点,这个点代表一个可以由程序使用的虚拟像素(比如: css像素),然后由相关系统转换为物理像素。
所以说,物理像素和设备独立像素之间存在着一定的对应关系,这就是接下来要说的设备像素比。
4.设备像素比(device pixel ratio)
设备像素比(简称dpr)定义了物理像素和设备独立像素的对应关系,它的值可以按如下的公式的得到:
设备像素比 = 物理像素 / 设备独立像素 // 在某一方向上,x方向或者y方向
5.rem
rem 是一个css单位,rem(font size of the root element)是指相对于根元素的字体大小的单位。简单的说它就是一个相对单位。看到rem大家一定会想起em单位,em(font size of the element)是指相对于父元素的字体大小的单位。它们之间其实很相似,只不过一个计算的规则是依赖根元素一个是依赖父元素计算。(这里的根元素指的是html)
三 几种解决方案
3.1 通过css3 的media queries,即媒体查询
这是一个pc的主页网站,pc和移动端做的统一适配
一般早期手机机型不多的时候采用的方案,原理是通过css3的media queries 的方式查询设备宽度,来执行不同的css代码。
这是一段css代码,在不同的屏幕宽度下设置不同的font-szie.
优点
-
media query
对移动和PC维护同一套代码的时候,基于bootstrap,适用于一些比较稳定的主站 - 图片修改简单,只需修改css文件
- 调整屏幕宽度的时候不用刷新页面即可响应式展示(最大的好处之一)
缺点
- 代码总量比较大,维护不方便,比较臃肿
- 兼顾大屏幕或高清设备,造成其他设备资源浪费,特别是加载图片资源,因为css是预读的,对于首屏加载时间是有影响的,尤其是图片比较多,需要加上懒加载
- 为了兼顾移动端和PC端各自响应式的展示效果,在做一些效果的时候只能牺牲取折中的方案
- 代码不够灵活,手机的机型越来越多,对新的手机做适配难度比较大,改动比较麻烦。
3.2 flex弹性布局
以为天猫h5首页为例
flex 的原理不在赘述,简单的说就是把父元素下的盒子分成了几份,无论屏幕大小,实现等比例的伸缩的一种css3的全新布局方式。
优点
- flex布局简单易用,作为css3的新属性,在h5页面中表现良好,能够动态的弹性伸缩
- 无需纠结于屏幕的尺寸、像素,等等一些问题
- 代码易于维护,布局方式简单、清晰
缺点
- 很抱歉的是,flex兼容性并不好,在某些机型上会有坑,兼容处理比较麻烦
- flex-direction与justify-content、align-items 等属性在一些特定的情况下 并不好用
3.3 rem + viewport 缩放 (目前金融商城采用的解决方案)
最开始的时候,很多采用的是媒体查询,但是随着机型的越来越多,媒体查询的方式越来越不适用。
rem上边我们已经介绍过,那么看看具体怎么用,这是一个简单的button,当页面根元素的font-size改变,页面整体都会跟着改变,相当于根元素是一个基准或者系数
也很像viewport的这种缩放的方式。
既然描述的听上去很完美,在不同机型上,直接改变根元素的font-size值或者viewport的缩放比例就可以了,的确之前也有单独用rem或者单独用viewport做适配的。
但是,最后老生长谈的还是回到了兼容性这个点上,纯rem的方式在背景和字体上会存在一些问题,毕竟是基于根元素计算来的,而不是真正的缩放。而viewport的方式在某些
浏览器的webview是有兼容性问题的,而且还存在一像素无法渲染的问题。
所以折中的我们采取了rem+viewport缩放的并行方案,根据屏幕的尺寸,动态计算rem的根元素和viewport的缩放比例。
具体代码的实现:(由于内网安全红线,代码示例的部分就省去了)
主要的代码逻辑:
setViewport部分,主要就是对ios和安卓做了机型的区分,和对是否第一次设置viewport做了判断。
setRem部分,主要就是根据屏幕的实际宽度设置根元素的font-size
在init函数里针对一些情况做了单独的处理
考虑了屏幕发生旋转、页面load的时候,重新计算rem
四 总结
布局方式和屏幕适配本来就是前端的一个比较头疼的问题,在日常的开发中花费掉了开发者大量的精力和时间,尤其是处理一些兼容性的问题。
而适配屏幕的方式也在一直进化和改变,肯定会有新的适配方案来代替现在的方案。
需要勤加总结和学习新的知识,保持自己的更新和迭代。