技术分享—移动端适配—长青.movbanner1.png

目录

  • 为什么需要做适配
  • 基本概念
  • 视口
  • 适配方案
  • 调研


device-sizes.png

为什么需要做适配

  • 各个移动端设备,屏幕尺寸、分辨率大小不一致
  • 让拥有不同屏幕大小的终端设备拥有一致的 UI 界面

高清屏幕带来的问题

  • 1px问题
  • 高清屏图片显示模糊

基本概念

  • 屏幕尺寸
  • 屏幕密度
  • 物理像素
  • 分辨率
  • 设备独立像素
  • 物理分辨率逻辑分辨率
  • CSS 像素
  • 设备像素比

屏幕尺寸

  • 屏幕对角线的长度,单位英寸
  • 1英寸 = 2.54厘米

设备尺寸.png

物理像素(设备像素)

  • 设备屏幕上真实存在的像素点
  • 是屏幕呈像的最小单位
  • 每个物理像素由3个颜色像素构成
  • 每个物理像素可以表示2^24种颜色

pixels.png

屏幕密度(PPI)

  • 屏幕密度是指一个设备表面上存在的像素数量,它通常以每英寸有多少像素来计算。
  • PPI = √(X^2+Y^2)/ Z

iphone 6 屏幕 PPI: √(750^2+ 1334^2)/ 4.7 = 325.61

物理分辨率

  • 物理分辨率是指纵横向上的物理像素点数
  • iphone6 屏幕分辨率: 750 * 1334

img-resolution.png
现在设备的物理分辨率在变得越来越大,这样就暴露出来一个问题

高清屏与超高清屏

设备独立像素(逻辑像素)

  • 计算机坐标系统中的一个点
  • 可以由程序使用的虚拟像素

dip.png

逻辑分辨率

  • 逻辑分辨率是指纵横方向上的设备独立像素点数

设备屏幕参数.png

CSS 像素

  • 虚拟像素
  • CSS 像素单位是 px 是一个相对的单位,主要使用在浏览器上,用来精确度量 Web 页面上的内容。
  • 一般情况之下,CSS 像素称可以等同于设备独立像素。
  1. <meta name="viewport" content="width=device-width, initial-scale=1" />

设备像素比(dpr)

  • 设备像素比简称为 dpr,其定义了物理像素和设备独立像素的对应关系。
  • 它的值可以按下面的公式计算得到:

    1. 设备像素比 物理像素 / 设备独立像素
  • 通过 JS 来获取 window.devicePixelRatio

模糊问题.webp


视口

开发网页时,head中总有这么一个标签:

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

什么是viewport

视口 (viewport) 代表当前可见的计算机图形区域。在 Web 浏览器术语中,通常与浏览器窗口相同,但不包括浏览器的 UI, 菜单栏等——即指你正在浏览的文档的那一部分。

  • 在尺寸较大的设备中,在这些设备上,应用显示区域不一定是全屏的,viewport 是浏览器窗口的大小。
  • 在大多数移动设备中,浏览器是全屏的,viewport 是整个屏幕的大小。
  • 视口在CSS标准文档中称为初始包含块
  • 可以使用 document.documentElement.clientWidth 获取视口宽度

    窄屏设备的问题

  • 早期移动设备物理像素点数宽度多数在 320、480 以及 640px

  • 需要不断的滚动来保证阅读的连续性,体验糟糕

放大 viewport

  • 页面缩小,需要通过放大和滑动来浏览细节。
  • 滚动条条问题依然存在
  • 限制了依据视口宽度做媒体查询机制的有效性

根据设备宽度而变化的视口

  • 可以使用媒体查询来做移动端适配,我们可以设置 viewport 宽度为 device-width,以保证媒体查询技术的有效性
  • 可以结合各种相对长度单位(%/rem/vw 等),设置合适的 viewport,以实现布局伸缩和内容大小固定的完美统一。

分类

  • 视觉视口
  • 布局视口
  • 理想视口

布局视口

  1. <meta name="viewport" width="device-width">
  1. 手机上,为了容纳为桌面浏览器设计的网站,默认的布局视口的宽度远大于屏幕的宽度,布局视口的出现,在极大程度上帮助了桌面网站到移动设备上的转移。可以通过document.documentElement.clientWidth 来获取。<br /> pc 端,单独一个 width 20%的元素最终拿到的值要根据初始包含块的 width 来决定,因为我们横向的布局都是按初始包含块开始填的,在移动端一样,不过我们这个时候应该叫它布局视口。

用户在缩放是视口的大小是如何变化的?

用户视角 浏览器视角
视口放大2.gif视口放大1.gif

视觉视口

视觉视口语设备屏幕一样宽,并且它的css像素的数量会随用户的缩放而改变visual viewport的宽度可以通过window.innerWidth 来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。

理想视口

视觉视口语设备屏幕一样宽,并且它的css像素的数量会随用户的缩放而改变visual viewport的宽度可以通过window.innerWidth 来获取,但在Android 2, Oprea mini 和 UC 8中无法正确获取。

以 iphone6 手机为例

  • 屏幕物理分辨率:750*1334
  • 屏幕逻辑分辨率:375*667 (screen.width/height)
  • 设备像素比(dpr):2 (window.devicePixelRatio)
  • 浏览器默认视口宽度:980 (document.documentElement.clientWidth)

    视口meta标签

  1. <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no" />
属性名 取值 描述
width device-width 或正整数 定义视口的宽度,单位为像素,一般为 device-width:表示宽度为设备屏幕的宽度
initial-scale [0.0-10.0] 定义初始缩放值,一般设置为 1.0
minimum-scale [0.0-10.0] 定义缩小最小比例,它必须小于或等于 maximum-scale 设置
maximum-scale [0.0-10.0] 定义放大最大比例,它必须大于或等于 minimum-scale 设置
user-scalable yes / no 定义是否允许用户手动缩放页面,默认值 yes

PPK的三大视口理论

在这里介绍《移动 web 手册》这本书中介绍了 3 大视口理论,分别为布局视口、视觉视口、理想视口

  • 在桌面浏览器上,浏览器的窗口是约束我们 CSS 布局的视口(又称为初始包含块)
  • 在手机上,桌面视口被拆分为俩个:布局视口和视觉视口,布局视口限制我们的 CSS 布局,视觉视口决定用户看的到什么
  • 视觉视口宽度:window.innerWidth
  • 布局视口宽度:document.documentElement.clientWidth
  • 理想视口,它是对设备来说最理想的布局视口尺寸。理想视口中的网页用户最理想的宽度,用户进入页面的时候不需要缩放。
    我只需要加入, 然而,这段代码其实也并不完美,在 IE 浏览器中,由于横屏竖屏的切换会对布局视口造成影响,为了解决这个兼容性的问题,最后再加上一句,就有了现在的:

适配方案

  • 响应式设计
  • 自适应设计

响应式设计方案

响应式设计方案,常见于 PC、移动等多端共用一套代码的场景,比如 bootstrap 站点
响应式设计例子.gif

自适应设计

为了在特定的设备上显示最好的视觉效果,大部分移动端产品都有了区分于 PC 的专门的 m 站。
其技术实现通常为:服务器根据浏览器请求的 user-agent 判断设备类型,然后返回(或重定向)对应的站点内容。

自适应设计主要有 2 类: 布局伸缩式、等比缩放式

布局伸缩式

常见于排版比较简单的信息流展示类业务。其布局特点一般为横向伸缩,竖向高度固定或由内容填充决定;文字图标等网页内容一般会固定大小,且在宽屏窄屏上的视觉大小保持一致。
伸缩式.gif

技术方案

  • 设置 viewport 宽度为 device-width,保证 px 为单位取值的一些文字图标等网页内容视觉上在宽窄屏大小一致。
  • 布局方案:灵活使用相对单位%或弹性布局,以保证布局的横向伸缩和容器内各元素的大小间距符合预期;

等比缩放式

等比缩放顾名思义整个页面根据屏幕宽度的不同进行等比缩放,常见于产品类、运营类等业务场景,
等比缩放.gif
等比缩放式

Flexible 方案

由于在 2014 年之前,视口单位(vw、vh)还没得到个浏览器厂商的支持, 淘宝的前端团队借助 js 控制 viewport 的能力, 使用 rem 单位,去模拟出 vw 的特性来实现整个页面内容的等比例缩放,在项目中引入flexible后,我们在页面上统一使用rem单位来布局页面。

vw_caniuse.png
1. 使用 rem 模拟 vw 特性适配多种屏幕尺寸

  • rem是以根元素的字体大小为基准。例:html的font-size: 16px,则1rem = 16px
  • Flexible将整个页面的宽度切成了10份,然后将计算出来的页面宽度的1/10设置为html节点的fontSize,也就意味着,之后我们在当前页面的html节点的子节点上应用rem为单位时都是按照页面比例来计算的。
    1. var docEl = document.documentElement;
    2. function setRemUnit() {
    3. var rem = docEl.clientWidth / 10;
    4. docEl.style.fontSize = rem + 'px';
    5. }
    6. setRemUnit();

2. 控制 viewport 的 width 和 scale 值适配高倍屏显示

  • 设置viewport的width为device-width,改变浏览器viewport的默认宽度为理想的视口宽度,从而使得用户可以看到完整的布局的内容。
  • 等比设置viewport的initial-scale、maximum-scale、minimum-scale的值,从而实现1物理像素=1css像素,以适配高倍屏的显示效果(就是在这个地方规避了的“1px问题”)
    1. var metaEL = doc.querySelector('meta[name="viewport"]');
    2. var dpr = window.devicePixelRatio;
    3. var scale = 1 / dpr;
    4. metaEl.setAttribute(
    5. 'content',
    6. 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no',
    7. );

使用视口单位

  • vw(Viewport’s width):1vw 等于视口宽度的 1%
  • vh(Viewport’s height) :1vh 等于视口高度的 1%
  • vmin : vw 和 vh 中的较小值
  • vmax : 选取 vw 和 vh 中的最大值

viewport-unit.jpg

高清屏图片模糊问题

解决方法

在 dpr=2 的屏幕上展示两倍图(@2x),在 dpr=3 的屏幕上展示三倍图(@3x)

  1. image-set

    1. .avatar {
    2. background-image: url('conardLi_1x.png');
    3. background-image: -webkit-image-set('conardLi_2x.png' 2x, 'conardLi_3x.png' 3x);
    4. }
  2. 使用 img 标签的 srcset 属性,浏览器会自动根据像素密度匹配最佳显示图片

    1. <img src="avatar_1x.png" srcset="avatar_2x.png 2x, avatar_3x.png 3x" />
  3. svg
    svg的全称是可缩放矢量图(Scalable Vector Graphics)。不同于位图的基于像素,SVG 则是属于对图像的形状描述,所以它本质上是文本文件,体积较小,且不管放大多少倍都不会失真。


调研

小红书

  • 使用 rem 适配
  • 最大基准值为 60px
  • 字体和页面都进行缩放
  • 配合 媒体查询,限制 body 的最大宽度
  1. @media screen and (min-width: 768px) body {
  2. width: 450px !important;
  3. }

拍拍贷

  • vm 适配
  • 不限制页面宽度

饿了么

  • rem + vw 适配
  • 对 viewport 进行了缩放
  • html 元素的 font-size 依然由 px 指定
  • 具体元素的布局上使用 vw + rem 的形式
  • 没有限制布局宽度

携程

  • px+flex+百分比
  • 固定 1 倍 vieport
  • 设置 body 的最大宽度为 max-width: 540px;

总结

  • 新闻,社区等可阅读内容较多的场景:px+flex+百分比
  • 对视觉组件种类较多,视觉设计对元素位置的相对关系依赖较强的移动端页面:vw + rem

谢谢观看


附录

  1. 深入浅出移动端适配
  2. 彻底搞懂移动Web开发中的viewport与跨屏适配
  3. 关于各种像素概念和前端长度单位的理解
  4. The Ultimate Guide To iPhone Resolutions