移动端适配 扫盲指南

2022-11-30

响应式设计和自适应设计

响应式

响应式设计即 RWD(Responsive Web Design),理论上响应式界面能够适配不同的终端,一切能用来为各种分辨率和设备性能优化视觉体验的技术

自适应

自适应设计即 AWD(Adaptive Web Design),有可能会针对移动端减去内容,减去功能

两者对比

zdq84s.png

基础概念

设备独立像素(DIP)

设备独立像素 = CSS像素(px) = 逻辑像素

打开 Chrome 浏览器的开发者工具,使用 Ctrl + Shift + M:

zdqH2t.png

如图所示:375 * 667 就是 iPhone 6/7/8 的设备独立像素。

物理像素

物理像素 = 设备屏幕分辨率

显示屏是由一个个物理像素点组成的,从制成的时刻就固定不变的。

iPhone 6:zdLlM6.png

设备像素比(DPR)

设备像素比描述的是未缩放状态下,物理像素和设备独立像素的初始比例关系。

DPR = 物理像素 / 设备独立像素

由此计算公式可以简单计算出 iPhone 6 的 DPR = 1334 / 375 = 2

苹果公司将 dpr > 1 的屏幕称为视网膜屏幕(Retina)

zdOiYd.png

H5 适配的两个维度:

  • 适配不同屏幕大小,也就是适配不同屏幕下的 CSS 像素
  • 适配不同像素密度,也就是适配不同屏幕下 dpr 不一致导致的一些问题

移动端屏幕适配方案

rem 适配

  • 等比放大(相当于更大的屏幕只是看到更大的内容而不是更多的内容)

  • rem 就是相对于根元素 html 的 font-size 来做计算,配合 JavaScript 模拟 vw 的特性,属于等比缩放。

  • 当初用于浏览器支持 viewport 特性程度低。

将屏幕宽度等分为 100 份,每一份的宽度用 x 表示;如果将 x 根元素的 font-size 数值,那么子元素的相关属性数值使用 rem 即可随着屏幕等宽变化。

通过使用 Javascript 动态设置 html 的字体大小恒等于屏幕宽度的百分之一,一般需在页面 dom ready、resize 和屏幕旋转中设置:

document.documentElement.style.fontSize = document.documentElement.clientWidth / 100 + 'px';

假设给出的设计图为 750 * 1334,其中一个元素宽度为 200pxwidth: 200 / 750 * 100 = 26.67 rem

优缺点

优点:rem 的兼容性能低到 ios 4.1、android 2.1

缺点:

  • 字体大小不能使用 rem(一般使用媒体查询控制 font-size 大小)

  • 1px 边框在高清屏下的显示问题,需要自行处理

  • 在 PC 端浏览会崩坏,一般设置一个最大宽度

let clientWidth = document.documentElement.clientWidth;
clientWidth = clientWidth < 780 ? clientWidth : 780;
document.documentElement.style.fontSize = clientWidth / 100 + 'px';

body {
	margin: auto;
	width: 100rem;
}

相关技术方案:flexible(amfe-flexible 或者 lib-flexible) + postcss-pxtorem

vw 适配

  • 等比缩放(相当于更大的屏幕只是看到更大的内容而不是更多的内容)
  • rem 需要借助 Javascript 进行动态修改根元素的 font-size,而 vw/vh(vmax/vmin) 的出现则很好弥补 rem 需要 Javascript 辅助的缺点。

根据 CSS Values and Units Module Level 4: vw 等于初始包含块(html元素)宽度的1%,也就是

  • 1vw 等于 window.innerWidth 的数值的 1%
  • 1vh 等于 window.innerHeight 的数值的 1%

zwPdrd.png

rem 适配中的例子:26.67 rem 可换成 26.67 vw

优缺点

优点:CSS 原生支持,而且目前兼容性大多数手机是支持的,也不需要加载 Javascript

缺点:

  • 1px 边框在高清屏下的显示问题,需要自行处理
  • 在 PC 端浏览会崩坏,一般设置一个最大宽度

相关技术方案:postcss-px-to-viewport

px 适配

px + calc + clamp

适合新闻、社区等可阅读内容较多的场景;大屏用户想要看到更多的内容

按照 750 的设计稿,300 是在 750 中 header 的高度:

/* style.css */

:root {
  --ideal-viewport-width: 750;
  --current-viewport-width: 100vw;
  --min-viewport-width: 320px;
  --max-viewport-width: 1440px;
  --clamped-viewport-width: clamp(var(--min-viewport-width),
      var(--current-viewport-width),
      var(--max-viewport-width));
}

body {
  width: 100vw;
}

header {
  height: calc(300 * var(--clamped-viewport-width) / var(--ideal-viewport-width));
  line-height: calc(300 * var(--clamped-viewport-width) / var(--ideal-viewport-width));
  text-align: center;
  background-color: #f2f2f2;
}
优缺点

优点:解决失去像素的完美性;屏幕低于或高于某个阈值,通常就会出现布局的移动或文字内容的溢出

1px线

UI 稿中 1像素指在 Retina 屏显示1 物理像素宽度,而不是1 CSS 像素宽度

  • 在 dpr = 1 时,此时 1 物理像素等于 1 CSS 像素宽度
  • 在 dpr = 2 时,此时 1 物理像素等于 0.5 CSS 宽度像素,可以认为 border-width: 1px 这里的 1px 其实是 1 CSS像素宽度,等于 2 像素物理宽度,设计师其实想要的是 border-width: 0.5px
  • 在 dpr = 3 时,此时 1 物理像素等于 0.33 CSS 宽度像素,设计师其实想要的是 border-width: 0.333px

使用 0.5px 吗?iOS 8及以上,苹果系统支持;但是 iOS 8以下和 Android(部分低端机),会将0.5px 显示为 0px

方案

渐变实现

  • background-image: linear-gradient()

使用缩放实现

  • transform: scaleY()

使用图片实现

  • base64

使用 SVG 实现

  • 嵌入 background url

border-image

  • 低端机下支持度不好

以上都是通过 CSS 的媒体查询来实现的

@media only screen and (-webkit-min-device-pixel-ratio: 2),
    only screen and (min-device-pixel-ratio: 2) {}
@media only screen and (-webkit-min-device-pixel-ratio: 3),
    only screen and (min-device-pixel-ratio: 3) {}

图片适配

  1. 消除多余的图像资源
  2. 尽可能利用 CSS3\SVG 矢量图像替代某些光栅图像(jpg\png)
  3. 谨慎使用字体图标,使用网页字体取代在图像中进行文本编码
  4. 选择正确的图片格式
  5. 为不同 DPR 屏幕提供最适合的图片尺寸
srcset
<div class='illustration'>
  <img src='illustration-small.png'
       srcset='images/illustration-small.png 1x,
               images/illustration-big.png 2x'
       style='max-width: 500px'/>
</div>

上面 srcset 里的 1x,2x 表示 像素密度描述符,表示

  • 当屏幕的 dpr = 1 时,使用 images/illustration-small.png
  • 当屏幕的 dpr = 2 时,使用 images/illustration-big.png

字体适配

字体大小

浏览器有最小字体限制

  • PC上最小 font-size = 12px
  • 手机上最小 font-size = 8px
字体的选择展示
  • 使用系统字体能更好的与当前操作系统使用的相匹配
  • 使用各个支持平台上的默认系统字体

参考资料

移动端适配目前最好的解决方案是什么?
前端基础知识概述 -- 移动端开发的屏幕、图像、字体与布局的兼容适配

cd ..