1. 引言

自打盘古开天辟地,技术的变革就从未停下脚步。我们小前端慢慢也从静态页面到动态丰富的页面,再到现在需要扩展至多端平台的能力。看看我们的钢铁侠托尼大叔,从 Mark1 号的铁憨憨到 Mark50 号纳米战甲,从未停歇下脚步,咱家怎可安心当一个小切图仔呢?

Emmm~回归正题,我们现在移动端的应用场景愈来愈多,而移动 web 开发这种混合(hybrid)方式更是炙手可热,怎么说?学!!!

2. 移动 web 概述

说到移动端,那就离不开移动端 IOS、Android、Flutter 这些开发,而移动 web 顾名思义就是移动端开发 + web 开发。这里就要使用上 webview,它相当于浏览器,具有跨平台的能力。移动端开发基于 webview 的能力就能嵌入 h5 页面来实现移动 web

3. 适配概述

说到移动 web 开发,适配是第一个要解决的难题。首先看看 PC 和移动 web 常用的适配方式

PC:

  1. 外层:版心 + 定宽(比如淘宝的1190px)+ 居中
  2. 内层:盒子模型、表格、定高、定宽
  3. 流式布局:flex 布局、百分比

移动web:

  1. 定高、宽度百分比
  2. 流式布局:flex 布局、百分比
  3. Media Query(媒体查询)

补充一个响应式布局,可以相当于 flex + 媒体查询,来同时满足 pc 和 移动 web。接下来我将重点针对移动端的适配进行展开,主要包括:

  • viewport 视口和流式布局
  • css flex 和 media query媒体查询
  • rem 原理和适配方法

3.1 viewport 视口

说到 viewport,我先补充一些分辨率和视口相关的概念:

3.1.1 分辨率

这里说的像素是物理像素

  1. 像素:图片或电子屏幕的最小组成单位
  2. 屏幕分辨率:屏幕由多少个像素点组成,比如 iphone XsMax 的屏幕分辨率是 2688x1242,即表示手机分别在垂直和水平上所具有的像素点数
  3. 图像分辨率:图片含有的像素数,道理同屏幕分辨率
  4. PPI(PixelPerInch):每英寸包括的像素数
  5. DPI(DotPerInch):每英寸包括的点数。这里的点是一个抽象的单位,它可以是屏幕像素点、图片像素点也可以是打印机的墨

基于以上的概念,接下来看看一些问题:

  • 什么是设备独立像素和设备像素比?
  • 什么是 css 像素和物理像素?

设备独立像素和设备像素比

如果熟悉 android 的小伙伴,一定会知道 dp 这个单位,它的来源是设备独立像素 (DeviceIndependentPixels) 这玩意儿,可以简称 DIP 或 DP。为什么需要有设备独立像素这么一个东西呢?

正是因为乔布斯老爷的 iphone4 首次提出了 RetinaDisplay (视网膜屏幕) 的概念,来满足高分辨率手机中页面的元素能和低分辨率手机大小保持一致。实际效果是 iphone4 把 2*2 的像素当成 1 个像素使用,也就是我们开发常说的 2 倍屏,再到后来的 iphone X 又升级为了 3 倍。这个比例就是设备像素比(device pixel ratio),简称 dpr。而设备独立像素就像是作为基准参照物,来代表元素所占据的像素。

css 像素和物理像素

这里有一个公式:页面的缩放系数 = css像素/设备独立像素

也就是当页面的缩放系数为100%时,css像素和设备独立像素是相等的。也就是在页面开发时,若设置了 10px 的 css像素,在 iphoneX 这样的 3 倍屏手机上便占据了 30px 的物理像素

3.1.2 视口

视口包括了布局视口、物理视口和理想视口,他们在屏幕适配中起着非常重要的作用

布局视口(layout viewport)

布局视口是网页布局的基准窗口,我们顶层元素若使用百分比的方式进行设置宽高则和布局视口有关。这个浏览器的初始视口大小和厂商有关,在 pc 端它就等于浏览器的窗口大小,移动端大部分为 980px

我们可以通过调用 document.documentElement.clientWidth/clientHeight 来获取布局视口大小

可视视口(visual viewport)

可视视口是可视范围的大小,即用户通过屏幕看到的范围,它会随着浏览器缩放而改变

我们可以通过调用 window.innerWidth/innerHeight 来获取可视视口大小

理想视口(ideal viewport)

理想视口对比.jpg
如上图所示,若未做适配,浏览器会将页面内容刚好缩放至 visual viewport 的可视区域内,即 pc 端的页面在移动端展示时会等比例进行缩放,导致文字和内容太小。这明显不是我们想要的效果。这时候就引入了一个理想视口,简单可理解为网站页面在移动端展示的理想大小

那么可想而知,理想视口的宽度和可视视口的宽度相等,就能达到我们想要的效果,那么就要使用 meta viewport 来进行实现,下小节即进行介绍

我们可以通过调用 screen.width/height 来获取理想视口大小

meta viewport

如上节所述,为了在移动端让页面获得更好的显示效果,我们必须让布局视口、可视视口都尽可能等于理想视口,这里主要涉及两个配置项:

  1. device-width 就等于理想视口的宽度,所以设置 width=device-width 就相当于让布局视口等于理想视口
  2. 由于 initial-scale = 理想视口宽度 / 可视视口宽度,所以我们设置 initial-scale=1;就相当于让可视视口等于理想视口

详细使用和配置如下:

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