在 PC 端,除了数据可视化和中后台这样一些全屏设计场景需要适配,绝大多数的网页采用的都是固定尺寸设计,由于 1366+ 的屏幕尺寸大于常用的固定设计尺寸,网页按设计尺寸 1:1 还原即可,不需要考虑适配。而在移动端,由于屏幕尺寸大小不一,且采用全屏的设计风格,则需要做适配。
目前移动端端内主流适配方案有:
1 | * 流体式/弹性式; |
注:适配方案还有设备独立像素和 Media Query(query 的是逻辑像素)。
抽象的设备独立像素解决的是端内高密度屏的适配(底层图形系统会根据 DPI 自动换算为物理像素),Media Query 解决的是跨端的设计风格适配,而流体、Rem、Layout Viewport Scale 解决的是端内设计要素(盒模型、字体、图片…)的适配(同一 UI 的整体缩放,没有设计上的差异)。
在设计要素适配中,“盒模型”和“字体”只需要考虑大小,而“图像”相对复杂一些,需要考虑流量、清晰度等问题,常见的解决方案有:矢量化、字体化、image-set 等。
流体式
这是最早使用的适配方案,也是最常用的一种,特别是在响应式 UI 框架中(比如 Bootstrap)。其原理是,完美视口下,选需要兼容设备的最小宽度(一般都是 320px)来布局,垂直方向的高度和间距使用定值,水平方向用百分比、定值、flex…,最终达到“当手机屏幕变化时,横向拉伸或者填充空白的效果”。Eg:百度、亚马逊。
使用方法
- 步骤一,设置 Layout Viewport 为完美视口
1 | <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> |
- 步骤二,切图布局
小往大适配,选需要兼容设备的最小尺寸还原设计稿(一般都是 iPhone5 的 320px,这是当前主流手机中的最小尺寸),当屏幕变宽时,简单的填充空白即可(如果从大到小,小分辨率设备上,就会出现滚动条)。
注:选主流中最小分辨率机型来进行设计(640 * 1334),CSS 尺寸 = 视觉稿尺寸/dpr = 640/2 = 320
。前端在高清视觉稿下切图,使得图片兼容 Retain,在 CSS 中缩放;
1 | .img {max-width: 100%;} |
优缺点
- 优点
1 | * 简单方便; |
- 缺点
1 | * 还原度不精确(如果以开发规范驱动设计就不会存在这个问题) --- 在分辨率不同的设备上,页面的字体大小,内容尺寸都是一样的,不同的是,大屏的内容间的空隙比小屏的大; |
Layout Viewport Scale
设计稿、页面布局、Layout Viewport 使用统一宽度,前端按设计稿的尺寸还原,使用定值单位(px、em…),利用浏览器『自身缩放』完成适配。Eg:网易新闻。
使用方法
- 步骤一,设置 Layout Viewport 的宽度
一般会设为 640。与流体式一样,这两种方案的核心都是视口的确定。
1 | <meta name="viewport" content="width=设计稿的宽度"> |
该方案使用固定宽度值,需要考虑主流分辨率,确定一个合适的值,既不能选大了,也不能选小了,选大了可能会使得在小分辨率屏幕下像素丢失,选小了又可能会使得在大分辨率屏幕下模糊。
- 步骤二,缩放
正常浏览器都会将 Layout Viewport
自动缩放至屏内(视觉视口),不能自动缩放的浏览器要手动计算 scale 值。
1 | var viewport = function () { |
以下面动态生成的结果为例,640 是根据设计稿定下的,0.5(1/dpr,或者 320/640) 是根据屏幕宽度动态生成的。生成的 viewport 告诉浏览器网页的布局视口使用 640px,然后把页面缩放成 50%,图片、文字等等所有元素都被缩放在手机屏幕中,这是绝对的等比例缩放。
1 | <meta name="viewport" content="width=640,initial-scale=0.5,maximum-scale=0.5,minimum-scale=0.5,user-scalable=no"> |
优缺点
- 优点
1 | * 开发简单 --- 缩放交给浏览器,完全按视觉稿切图; |
- 缺点
1 | * 像素丢失 --- 对于一些分辨率较低的手机,可能设备像素还未达到指定的 viewport 宽度,此时屏幕的渲染可能就不准确。比较常见的是边框“消失”了,不过随着手机硬件的更新,这个问题会越来越少; |
REM
“流体式”、“Layout Viewport Scale” 这两种适配方案,都存在缺陷,一个优秀的适配方案应做到以下两点:
1 | * UI 的精确还原与适配 |
VW + Rem 就是这样的一个方案。其原理是,屏幕联动 html font-size vw,html font-size 联动 rem( html font-size value = 1 rem),来做到适配。
使用方法
- 定义规范
1 | * 设计规范。规定设计稿分辨率,推荐采用 1X 的设计方案(即手机 375,横屏 Pad 960,而不是 2X 的 750、1920),为了方便 figma 下,导入第三方 UI 组件 |
将基准值的定义为 100vw/10 = 10vw,而不是 100px(除以 19.2、12.8),这仅仅是规范,10vw 体现适配原则,容易理解,而 100px 在没有转换工具的条件下,方便了计算。
在没有转换工具的情况下,为了方便计算,我们会将 html faont-size 定义如下:
1 | /* 1920 的设计规范下还原的,base 为 1920px/19.2 = 100px,px 转 rem 除以 100 即可 */ |
直接在源码里面进行转换不利于源码的维护,在现代前端开发中推荐使用工程化工具转换。
- 使用步骤
1 | * 步骤一:定义 html font-size 基准值(一般会定为 10vw,绝大多数适配场景都是按宽度适配,如果按高度适配也可为 10vh) |
- 兼容处理
vw 不支持 Android 4.4 以下设备,这时候就需要对 vw 做兼容处理了。这里不想通过 JS 来解决此问题,本着逐渐增强,平稳退化的原则,选一个默认分辨率处理,比如手机就选 750 的分辨率:
1 | html { |
注:flexible 就是手淘团队在 Android 4.4- 设备不支持 vw 时的一个 JS 解决方案。