[TOC]
# 介绍
移动web端的开发长久以来,从最开始的宽度自适应,流动布局(fluid grid),慢慢的到 2010年5月份,Ethan Marcotte提出的一个概念 ”自适应网页设计”([Responsive Web Design](https://alistapart.com/article/responsive-web-design/)),这个概念可以说是现在移动web端设计的基石。
如何适配数不清的屏幕尺寸,曾经是困扰前端开发人员的一大难题。
响应式布局的解决方案无法实现真正的移动适配,它的适配只能解决pc大屏幕到手机小屏幕的问题,但是手机屏幕任然有很多种。
# 页面需求
这是尺寸标注图(标注了的效果图)(750*1334):
![](https://box.kancloud.cn/ee82fbdf252b32f6f8fd4bc3c3699c64_750x1334.png)
然后美工在 `750*1334` 的设计稿之上,按我的要求提供以下素材的切图:
![](https://box.kancloud.cn/6ab99f5c600358df508074530f3060f4_586x150.png)
包括两个下载按钮的背景图片,logo,底部梯形的渐变背景和body部分的mobile 背景图。注意这些图片都是在`750*1334`的设计稿里面切出来的,所以尺寸都是设计稿里的原始尺寸,比如android.png:
![](https://box.kancloud.cn/39fc2b64b8722911fd7b3ed99136f905_580x292.png)
考虑到retina显示屏的问题,结合下图的适配思路:
![](https://box.kancloud.cn/23c118942e23cffd8e7c16090e4bfae5_600x423.png)
我认为解决retina屏问题的可行方案是:
1)在`devicePixelRatio<=2`时,图片统一使用750设计稿的切图
2)在`devicePixelRatio>=2`时,图片统一使用`750*1.5=1125`,也就是所谓@3x设计稿的切图。
我把美工给我的在750*1334的设计稿下的切图都放在img/@2x 这个文件夹下:
![](https://box.kancloud.cn/962b05dcafd0c3b96aee69022fa0e034_589x179.png)
然后让她帮忙把750的设计稿矢量放大1.5倍,再按照同样的切图要求为我提供@3x的切图,并放在了img/@3x 这个文件夹下:
![](https://box.kancloud.cn/df69b640a5d4983acffc10abcea3f7e5_583x175.png)
@3x下的图片理论上尺寸应该等于@2x下的图片*1.5,不过我的切的没有这么完美。
有了前面的需求介绍和素材准备,下一步就是该引入核心的js文件,编写css样式了。
# 引入flexible.js
这一步其实非常简单,只要把 https://github.com/amfe/lib-flexible 源码里flexible.js的内容复制出来,在本地新建一个flexible.js的文件,打开粘贴进去就可以了,我把这个文件放在了`js/lib`下面:
![](https://box.kancloud.cn/7c342ceb240099979f1a0ef44b4da7c4_353x173.png)
接着在html页面里面,尽可能早的引入这个js文件(一句话总结:**在浏览器中文档流是从上往下加载渲染的。为了保证发生不必要的重绘或者是重排肯定是越早给根节点设置font-size值越好。**):
```html
...
<head>
...
<script src="js/lib/flexible.js?v=1450433481578"></script>
...
</head>
...
```
注:使用`lib-flexible`,通常不要写:
~~~
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no"/>
~~~
交给 `flexible.js` 自动处理。
然后在chrome的模拟器里面,选择iphone6,应该就能看到html的`font-size`已经被设置为`font-size: 75px`了:
![](https://box.kancloud.cn/f28ac4c6e1b5b7e61878c828f2540ea3_754x238.png)
# 编写CSS
基本要求:
1. 除`font-size`外(字体还是用px,比较好),其它大小都根据750标注稿的尺寸,转换成rem单位的值,转换方法为:标注稿尺寸 / 标注稿基准字体大小;
2. 标注稿基准字体大小 = 标注稿宽度 / 10,如标注稿宽为750,标注稿基准字体大小为75;标注稿宽为640,标注稿基准字体大小为64;(所以淘宝这个方案是可以在任意设计稿尺寸下使用的)
3. 如果需要设置`font-size`,可跟据html的`data-dpr`属性来处理,类似下面的写法:
```css
[data-dpr="2"] p {
font-size: 16px;
}
[data-dpr="3"] p {
font-size: 24px;
}
```
以安卓下载按钮的样式为例,说明这种用法。android.png的尺寸为:`414*80`,所以css这么写:
```css
.btn {
width: 414rem/@font-size-base;
height: 80rem/@font-size-base;
}
```
由于用了less,事先定义了一个变量来保存标注稿基准字体大小:
```
@font-size-base: 75;
```
所以px2rem的转换变得非常容易,如上所示。less编译之后,会将正确的rem值计算出来:
```css
.btn {
width: 5.52rem;
height: 1.06666667rem;
}
```
到此,`lib-flexible`的基本实践就结束了,不过还有一个问题,就是retina屏的问题,到现在都还没提到@3x下图的那些切图怎么办,其实很简单,借助html元素的data-dpr属性,可以轻松实现另一种媒介查询,以便在devicePixelRatio>=2的时候启用@3x下的图片,还是以安卓下载按钮的样式为例,写法是:
```css
.btn-android {
background-image: url("../img/@2x/android.png?v=@@version");
[data-dpr="3"] & {
background-image: url("../img/@3x/android.png?v=@@version");
}
}
```
这下就OK了,原先还不知道`data-dpr`有什么作用,现在看看,作用还是挺大的。
# 小结
我把源码发出来,有兴趣的人可以下载参考:[本页源码](http://files.cnblogs.com/files/lyzg/finance-h5.zip)。
注:
1) 由于使用了`grunt`构建,所以需要先安装node ,git,再通过npm安装`grunt` 和`bower`
2)考虑到将来可能要做全屏滚动的效果,所以这页面一开始就是用`fullpage.js`来做的,通过bower引入了jquery跟fullpage.js的库
3) 模块化用到了`requirejs`
4)运行`grunt default`完成构建,再运行grunt server启动静态服务器预览。
# 总结
* 都能适配所有的手机设备,对于 pad,网易与淘宝都会跳转到 pc 页面,不再使用触屏版的页面
* 都需要动态设置 html 的 font-size
* 布局时各元素的尺寸值都是根据设计稿标注的尺寸计算出来,由于 html 的 font-size 是动态调整的,所以能够做到不同分辨率下页面布局呈现等比变化
* 容器元素的 font-size 都不用 rem,需要额外地对 font-size 做媒介查询
最终我们采用了基于 rem 做宽度,viewport 缩放 的 解决方案,很好的实现了适配各类屏幕。
同时采用了 fekey(px To rem)来解决书写 rem 不方便的问题,这样我们在写样式的时候只要和按照**UE标准的750px**来就行了,fekey 会自动帮助我们转为 rem。经过测试在低端的 Android 机上或者是 dpr 等于2的 IPhone6s 和dpr等于3 的 IPhone6s plus 都能很好的按照交互图来展示。
可以说基于rem适配原理的这一套解决方案,我们已经能够轻松适配各种类型、各种大小的屏幕。
**最后还有一个情况要说明**:跟网易一样,淘宝也设置了一个临界点,当设备竖着时横向物理分辨率大于1080时,html的`font-size`就不会变化了,原因也是一样的,分辨率已经可以去访问电脑版页面了。
# 参考
[淘宝弹性布局方案lib-flexible实践](http://www.cnblogs.com/lyzg/p/5058356.html)
[移动端适配之REM](http://www.jianshu.com/p/dfa33d3be23c)
[使用Flexible实现手淘H5页面的终端适配](https://github.com/amfe/article/issues/17)
[白树-移动web页面使用字体的思考](http://www.cnblogs.com/PeunZhang/p/3592096.html)
https://segmentfault.com/a/1190000004524243
https://segmentfault.com/a/1190000008754170
https://segmentfault.com/a/1190000004344753
https://segmentfault.com/q/1010000005148519
https://segmentfault.com/a/1190000003690140
- 前言
- 中文字体
- 移动Web适配方案
- !移动Web基础!
- 详解适配相关概念
- 移动开发之设计稿
- 移动适配方案(一)
- 移动适配方案(二)
- vw+rem 实现移动端布局
- 移动端适配之雪碧图(sprite)背景图片定位
- 适配 iPhoneX
- 前端开发实战
- 打造自己的前端开发流程(Gulp)
- flexible.js案例讲解
- viewport 与 flexible.js解读
- 图片与字体
- 踩过的坑
- 浏览器默认样式
- 300ms点击延迟和点击穿透
- ios css
- CSS 常见问题
- Ionic v1混合开发
- Native App、Web App 、Hybrid App?
- ionic项目结构
- 混淆加密
- 解决问题
- cordova
- 环境配置
- 打包发布
- 问题
- 移动前端开发优化
- Web开发之抓包
- ===web移动开发资源===
- H5组件框架
- 调试集合
- 简单h5调试
- whistle
- devtools-pro