随着智能手机的普及,web 移动端的前景已经优于web电脑端。要跟随时代的潮流,那我们必然要学习 web 移动端的开发。
基础概念
Viewport(视窗)
简单的理解,viewport 是严格等于浏览器的窗口。
在桌面浏览器中,viewport 就是浏览器窗口的宽度高度。但在移动端设备上就有点复杂。
但在移动设备中,viewport 太窄,为了能更好为 CSS 布局服务,所以提供了 visual viewport(视觉的)和 layout viewport(布局的)两个 viewport。
-
layout viewport
如果把移动设备上浏览器的可视区域设为 viewport 的话,某些网站就会因为viewport 太窄而显示错乱,所以浏览器默认情况下把 viewport 设为一个较宽的值,比如 980px,这样的话即使是那些为桌面设计的网站也能在移动浏览器上正常显示了。这个浏览器默认的 viewport 叫做 layout viewport。 -
visual viewport
layout viewport 的宽度是大于浏览器可视区域的宽度的,所以我们还需要一个viewport 来代表 浏览器可视区域的大小,这个 viewport 就叫做 visual viewport。如下图中红线内区域就是浏览器的可视区域,也就是我们这里说的 visual viewport。
图片来自互联网
在手机上浏览器的工作过程是这样的,当你输入一个网址后,浏览器会去请求这个资源,假设是一个 HTML 页面,那么浏览器会先在它的 layout viewport 里面渲染整个页面,然后把整个页面缩放至 visual viewport 的大小,最后供我们查看。
各种单位
1 绝对长度单位
in(inch英寸)、cm(厘米)、mm(毫米)、pt(磅)、pc(pica)。
- in、cm、mm 和实际中的常用单位完全相同。
- pt 是标准印刷上常用的单位,72pt 的长度为1英寸。
- pc 也是印刷上用的单位,1pc 的长度为12磅。
绝对长度单位,虽然理解起来很容易,但是在网页的设计中很少用到。所以我们就忽略它们吧。
2 相对长度单位
网页设计中使用最多的长度单位,包括 px、em、rem 等。
- px
全称 pixel,在网页开发中一般指CSS像素,它是一种逻辑上的单位。这里要和图片的分辨中的px区分。 - em
相对于当前对象内文本的字体尺寸,国外使用比较多。比如当前对象的字体大小为 16px,那么 1em = 16px。 - rem
在 W3C 规范中是这样描述 rem 的:font size of the root element
。简单的理解,rem 就是相对于根元素<html>
的 font-size来做计算。
3 物理像素、设备独立像素、CSS像素
-
物理像素(physical pixel)
物理像素又被称为设备像素,简称 px。它是显示设备中一个最微小的物理部件。每个像素可以根据操作系统设置自己的颜色和亮度。正是这些设备像素的微小距离欺骗了我们肉眼看到的图像效果。如下图中每个手机对应的最小的单元格的宽度便是物理像素,显然不同的设备有着不同的物理像素。
-
设备独立像素(density-independent pixel)
设备独立像素也称为密度无关像素,简称 dp、dip 或 dips。可以想象成是一个物理尺寸,使同样的设置在不同手机上显示的效果看起来是一样的。 -
CSS 像素
CSS 像素是一个抽像的单位,主要使用在浏览器上,用来精确度量 Web 页面上的内容。一般情况之下,CSS 像素称为设备独立像素。
4 屏幕尺寸、屏幕分辨率、屏幕像素密度
-
屏幕尺寸
屏幕的对角线的长度,单位是英寸,1 英寸 =2.54 厘米。常见的屏幕尺寸有2.4、2.8、3.5、3.7、4.2、5.0、5.5、6.0 等。
图片来自互联网 -
屏幕分辨率
指在横纵向上的像素点数,单位是 px,1px=1 个像素点。一般以纵向像素横向像素来表示一个手机的分辨率,如 19601080。(这里的1像素值得是物理设备的 1 个像素点) -
屏幕像素密度
屏幕上每英寸可以显示的像素点的数量,单位是 ppi,即“pixels per inch”的缩写。屏幕像素密度与屏幕尺寸和屏幕分辨率有关,在单一变化条件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。
5 设备像素比(device pixel ratio)
设备像素比简称为 dpr,其定义了物理像素和设备独立像素的对应关系。它的值可以按下面的公式计算得到:
设备像素比 = 物理像素 / 设备独立像素
开发实战
meta标签
<meta>
标签有很多种,而这里要着重说的是 viewport 的 meta 标签,其主要用来告诉浏览器如何规范的渲染 Web 页面,而你则需要告诉它视窗有多大。在开发移动端页面,我们需要设置 meta 标签如下:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, maximum-scale=1.0, user-scalable=no">
- width: viewport 的宽度
- height: viewport 的高度
- initial-scale: 初始的缩放比例
- minimum-scale: 允许用户缩放到的最小比例
- maximum-scale: 允许用户缩放到的最大比例
- user-scalable: 用户是否可以手动缩放
在 html 页面 head 部分加上面的代码,这是移动手机端开发的第一步。这句话的意思是告诉浏览器不要使用默认的布局 viewport,而是设置 viewport 等于设备的宽度。设备的宽度是最好的 viewport,这样页面的视觉效果最好。
如此,当我们写好一个页面后,就不会存在电脑上看正常,手机上看很小。initial-scale 缩放是相对于 ideal viewport 来缩放的,当 initial-scale 越大,则 clientWidth 越小。比如 initial-scale 为 2,说明以前需要 2 px 表示的宽度,现在只需要 1 px 就能表示了。我们可以得出下面的公式:
ideal viewport / clientWidth = initial-scale
前端实现方案
虽然加上了如上的 meta 标签,但是还是存在诸多问题。其中最典型的便是Retina下,border:1px问题
。
设计师想要的 retina下 border: 1px,其实就是 1 物理像素宽,对于 css 而言,可以认为是 border: 0.5px;,这是 retina 下(dpr=2)下能显示的最小单位。
然而,无奈并不是所有手机浏览器都能识别 border: 0.5px,ios7 以下,android 等其他系统里,0.5px 会被当成为0px 处理。
这里给出一个手淘团队使用的方案,在整个手淘团队,有一个名叫 lib-flexible 的库,而这个库就是用来解决 H5 页面终端适配的。lib-flexible 是一个制作 H5 适配的开源库。
GitHub 地址:https://github.com/amfe/lib-flexible