最近抽空看了看移动端适配的一些文章,也结合自己的经验做一下总结以及对比。
那么,开始正题,首先说说到目前位置出现的一些关于移动端适配的技术方案:
- 通过媒体查询的方式即
CSS3
的meida queries
- 以天猫首页为代表的
flex
弹性布局 - 以淘宝首页为代表的
rem
+viewport
缩放 rem
方式
Meida Queries
meida queries
的方式可以说是我早期采用的布局方式,它主要是通过查询设备的宽度来执行不同的 css
代码,最终达到界面的配置。核心语法是:
1 | @media screen and (max-width: 600px) { /*当屏幕尺寸小于600px时,应用下面的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">
高度定死,宽度自适应,元素都采用px
做单位。
随着屏幕宽度变化,页面也会跟着变化,效果就和PC页面的流体布局差不多,在哪个宽度需要调整的时候使用响应式布局调调就行(比如网易新闻),这样就实现了『适配』。DEMO>>
rem
+viewport
缩放
这也是淘宝使用的方案,根据屏幕宽度设定 rem
值,需要适配的元素都使用 rem
为单位,不需要适配的元素还是使用 px
为单位。
实现原理
根据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
。
具体请查看 https://github.com/amfe/lib-flexible 或 https://www.npmjs.com/package/anima-hd.
rem
实现
说说我司【魅族】移动端的实现方式,viewport
也是固定的:<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
。
通过以下代码来控制rem
基准值(设计稿以720px
宽度量取实际尺寸)
1 | !function (d) { |
css
通过sass
预编译,设置量取的px
值转化rem
的变量$px: (1/100)+rem;
;
1像素边框高清
淘宝实现方式
上面说到的淘宝的实现方式即rem
+viewport
缩放来实现。
transform: scale(0.5)
CSS
代码:
1 | div{ |
缺点:
- 圆角无法实现,实现4条边框比较麻烦,并且只能单独实现,如果嵌套,会对包含的效果产生不想要的效果,所以此方案配合:after和before独立使用较多。
box-shadow
实现方法:
利用CSS对阴影处理的方式实现0.5px的效果。
1 | -webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5); |
优点:
基本所有场景都能满足,包含圆角的button,单条,多条线。
缺点:
- 颜色不好处理, 黑色
rgba(0,0,0,1)
最深的情况了。有阴影出现,不好用。 - 大量使用
box-shadow
可能会导致性能瓶颈。 - 四条边框实现效果不理想。
图片实现
使用 background-image
实现1px有两种方式: 渐变 linear-gradient
或直接使用图片(base64
)。
渐变 linear-gradient
(50%有颜色,50%透明)
单条线:
1 | div { |
多条线:
1 | div { |
优点:
- 可以设置单条,多条边框
- 可以设置颜色
缺点:
- 大量使用渐变可能导致性能瓶颈
- 代码量大
- 多背景图片有兼容性问题