移动端适配必须掌握的基本概念和适配方案

随着技术的发展,移动设备越来越流行,并且不同设备间屏幕尺寸和屏幕像素的差异,移动端开发面临着多分辨率适配的问题。

基本概念

响应式开发本质时针对多种屏幕做适配,在实际开发中,通常情况下时针对主流的设备进行适配。在开发前,必须掌握几个基本概念:

  • 物理像素:即屏幕的实际像素点。像素是屏幕设备的最小显示单元,如 iPhone4 的屏幕分辨率是640x960像素,即 iPhone4 的屏幕由横向640个像素和纵向960个像素排列组成。
  • 设备独立像素:即逻辑像素,用于定义应用的 UI(UI即用户界面,这里指的是定义应用界面的各个元素的大小)。苹果 iPhone4 首次提出了 Retina Display(视网膜屏幕)的概念,在 iPhone4 使用的视网膜屏幕中,把 2x2 个像素当 1 个物理像素使用,即使用 2x2 个像素显示原来 1 个物理像素显示的内容,从而让 UI 显示更精致清晰,这 2x2 个像素即使逻辑像素。
  • 屏幕像素比(device pixel ratio 简称 dpr):即物理像素与逻辑像素的比值。

常见设备宽高:
| 设备名称 | 物理像素 | 设备独立像素 | 屏幕像素比 |
| :—–| :—- | :—- | :—- |
| iPhone4 | 640x960 | 320x480 | 2 |
| iPhone6,6S,7 | 750x1334 | 375x667 | 2 |
| iPhone6 Plus,6S Plus,7 Plus | 1080x1920 | 414x736 | 3 |
| Galaxy S4, S5 | 1080x1920 | 360x640 | 2 |
| Galaxy Note4 | 1440x2560 | 360x640 | 4 |
| iPad mini 2, 3 | 1536x2048 | 768x1024 | 2 |

视口(Viewport)

视口(Viewport)是指当前可见的计算机图形区域,在浏览器中,是指能用来显示网页的区域。视口当前可见的部分叫做可视视口(visual viewport)。整个网页所占据的区域(包括可视也包括不可视的区域)叫做布局视口(layout viewport)。当可视视口比布局视口小时,浏览器网页就会出现横向滚动条,以支持用户浏览整个网页的内容。

通常情况下,大多数移动设备的 Viewport(一般指布局视口)的宽度都是 980 像素,而可视视口(即设备独立像素)通常都小于 980 像素。为了禁止出现横向滚动条,不得不设置设备的 Viewport。通过在 Head 元素中使用 Meta 标签来设置 Viewport 属性。常用的 Viewport 设置如下:

1
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">

Viewport 属性:
| 属性 | 含义 | 取值 |
| :—–| :—- | :—- |
| width | 定义视口的宽度,单位为像素 | 正整数或 device-width(设备的宽度) |
| height | 定义视口的高度,单位为像素 | 正整数或 device-height(设备的高度) |
| initial-scale | 定义初始缩放比例 | 整数或小数 |
| maximum-scale | 定义允许用户缩放到的最大比例 | 整数或小数 |
| minimum-scale | 定义允许用户缩放到的最小比例 | 整数或小数 |
| user-scalable | 定义是否允许用户缩放 | yes或no |

适配方案

对于移动端适配的方案,市面上有很多种。细心观察会发现,实际上这些适配方案是基于两种不同的设计思想而产生的。一种是通过缩放处理屏蔽屏幕尺寸和分辨率的影响,保证内容元素数量的一致性。这种做法产生的结果是屏幕尺寸越大的设备显示的内容元素越大,反之亦然。另一种是不进行缩放处理,保证内容元素大小的一致性。这种做法产生的结果是屏幕尺寸越大的设备在横向上显示的内容元素越多,反之亦然。

rem 适配

rem 适配是缩放处理设计思想的典型代表。rem 是一个相对单位,它永远相对于根元素(html)的字体大小,这个特性方便了统一管理元素的大小,非常适合用来处理布局。rem 适配通常采用如下的 viewport 设置:

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

如何合理设置 rem 的大小呢?通常将页面宽度进行 10 等分,即:

1
const rem = document.documentElement.clientWidth / 10

这样,rem 的大小完全是随屏幕正比变化,就能根据设计稿尺寸换算页面元素和字体的大小。以常用的 750px 设计稿尺寸为例,假设设计稿的某个字体大小是 40px,换算成 rem 应该为 40 / 75 = 0.53333rem。当然这样计算很麻烦,可以选择使用构建工具postcss-pxtorem简化这些工作。

注意:并非所有单位都需要转换成 rem,通常只对需要等比缩放的元素进行 rem 换算,对于不需要缩放的元素,比如边框阴影,使用 px 等其他单位。实际开发中,应该以 rem 单位为基础,同时结合其他单位协同工作。

vw 适配

vw 是一个相对于 viewport 的单位,100vw 就等于 viewport 的宽度。vw 适配同样是一个缩放处理设计思想的适配方案,得益于现代浏览器对 vw 单位的良好支持性而流行,它是比 rem 适配更优秀的适配方案。vw 适配通常采用如下的 viewport 设置:

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

vw 适配如何换算元素大小呢?使用公式:(元素大小 / 设计稿大小) 100vw 将元素大小转换为 vw 单位的大小。以常用的 750px 设计稿尺寸为例,假设设计稿的某个字体大小是 40px,换算成 vw 单位大小应该为 (40 / 750) 100vw = 5.33333vw。同样可以选择使用构建工具postcss-px-to-viewport简化工作流程。

vw 适配和 rem 适配出自同一种设计思想,它们极其相似,vw 适配同样需要结合其他单位协同工作。

弹性盒(Flexbox)适配

弹性盒(CSS Flexible Box Layout Module 简称 Flexbox)是一种用于在单个维度(行或列)中显示项目的布局模型。当页面需要适应不同的屏幕大小以及设备类型时确保元素拥有恰当的行为的布局方式,提供一种更加有效的方式来对一个容器中的子元素进行排列、对齐和分配空白空间。Flexbox 布局的两个基本概念:

  • 容器:弹性布局的父元素(display=flex的元素)。
  • 项目:弹性布局容器中的每一个子元素。

弹性盒适配就是采用了 Flexbox 布局模型的适配方案,这种适配方案通常使用如下的 viewport 设置:

1
<meta name="viewport" content="width=device-width, initial-scale=1">

使用弹性盒适配的优点是不需要进行单位转换,因为其不需进行缩放处理,因此通常情况下都使用 px 单位。弹性盒适配的基本原则是:

  • 内容流式:即弹性项目(弹性布局容器中的每一个子元素)的填充内容使用流式布局。
  • 布局弹性:即涉及元素排列、对齐和空间分配时,使用弹性盒进行布局。

目前,没有完美的适配方式。实际开发中,应根据项目的需求和团队的素质选用合适的方案。