目前出现的关于移动端适配的方案有:

  • 通过媒体查询的方式即 CSS3 的 meida queries
  • 以天猫首页为代表的 flex 弹性布局
  • 以淘宝首页为代表的 rem+viewport 缩放
  • rem 方式

Meida Queries

通过查询设备的宽度来执行不同的 css 代码,最终达到界面的配置。

1
2
3
@media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的CSS样式*/
/*你的css代码*/
}

优点

  • media query可以做到设备像素比的判断,方法简单,成本低,特别是对移动和 PC 维护同一套代码的时候。目前像Bootstrap等框架使用这种方式布局
  • 图片便于修改,只需修改 css 文件
  • 调整屏幕宽度的时候不用刷新页面即可响应式展示

缺点

  • 代码量比较大,维护不方便
  • 为了兼顾大屏幕或高清设备,会造成其他设备资源浪费,特别是加载图片资源
  • 为了兼顾移动端和 PC 端各自响应式的展示效果,难免会损失各自特有的交互方式

Flex 弹性布局

以天猫的实现方式进行说明:
它的viewport是固定的:<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

随着屏幕宽度变化,页面也会跟着变化,效果就和 PC 页面的流体布局差不多

rem+viewport 缩放

根据rem将页面放大dpr倍, 然后viewport设置为1/dpr

  • 如 iphone6 plus 的 dpr 为 3, 则页面整体放大 3 倍, 1px(css 单位)在 plus 下默认为 3px(物理像素)
  • 然后viewport设置为 1/3, 这样页面整体缩回原始大小. 从而实现高清。

这样整个网页在设备内显示时的页面宽度就会等于设备逻辑像素大小,也就是device-width。这个device-width的计算公式为:
设备的物理分辨率/(devicePixelRatio * scale),在scale为 1 的情况下,device-width = 设备的物理分辨率/devicePixelRatio

rem 实现

viewport也是固定的:<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

通过以下代码来控制rem基准值(设计稿以720px宽度量取实际尺寸)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
!(function (d) {
var c = d.document;
var a = c.documentElement;
var b = d.devicePixelRatio;
var f;

function e() {
var h = a.getBoundingClientRect().width,
g;
if (b === 1) {
h = 720;
}
if (h > 720) h = 720; //设置基准值的极限值
g = h / 7.2;
a.style.fontSize = g + "px";
}

if (b > 2) {
b = 3;
} else {
if (b > 1) {
b = 2;
} else {
b = 1;
}
}
a.setAttribute("data-dpr", b);
d.addEventListener(
"resize",
function () {
clearTimeout(f);
f = setTimeout(e, 200);
},
false
);
e();
})(window);

css通过sass预编译,设置量取的px值转化rem的变量$px: (1/100)+rem;