在众多移动设备中,前端开发人员如何在不同屏幕大小,不同程度的高清屏下去百分百的还原设计稿,从来都不是一件简单的事情,需要考虑众多因素,权衡利弊,做出取舍,结合需求去选择最合适的方案。
面临的问题
在不同大小和高清的屏幕下:
- 如何保证 界面布局 一致性:不错乱,不变形
- 如何保证 字体大小 一致性:大屏显示更大,小屏显示更小或更多
- 如何保证 1px边框 一致性:不同的高清屏也在正常显示1px的高度大小
- 如何保证 图片清晰度 一致性:不同大小和高清屏下都能看到清晰的图片
如果把这几个问题按重要程度排序的话,我想应该是这样的:
布局 > 字体大小 > 1px边框 > 高清图
尺寸与概念
这里不去详细介绍各种尺寸概念了,如果还有不清楚,请参考下面几篇文章,基本上都是以图片的形式介绍的非常仔细了,也完全可以做为UI设计师的参数标准!
移动端设计规范及适配尺寸
常见的移动端尺寸设计参考
iOS8 最新设计参考指南
布局
方案一 百分比布局
使用子元素在父元素下的百分比为单位,使用子元素在不同屏幕宽度下宽度表现一致
利用img标签的特性,只设宽度等图片加载完,这种方法会导致大量的重排,并且非固定高度会导致懒加载等功能难以实现
缺点:
- 宽度可以随屏幕适应,但高度不能,宽屏下会被拉伸,具体表现为,iphone 4中看到的是正方形,而到了iphone 6s中看到的是长方形
- 需要手动计算子元素在父元素下的百分比,计算麻烦
- 百分比的大小往往需要精确到小数位6到8位
方案二 媒体查询调整
- 一种是是结合百分比或flex布局,对特定的模块在特定的屏幕宽度范围内做调整
- 另一种是结合rem, 对不同屏幕宽度范围内的设备设置不同的rem参照字体大小
html{font-size:10px}
@media screen and (min-width:321px) and (max-width:375px){html{font-size:11px}}
@media screen and (min-width:376px) and (max-width:414px){html{font-size:12px}}
@media screen and (min-width:415px) and (max-width:639px){html{font-size:15px}}
@media screen and (min-width:640px) and (max-width:719px){html{font-size:20px}}
@media screen and (min-width:720px) and (max-width:749px){html{font-size:22.5px}}
@media screen and (min-width:750px) and (max-width:799px){html{font-size:23.5px}}
@media screen and (min-width:800px){html{font-size:25px}}
缺点:
无法完全适配Android设备各种屏幕,无法保证显示的一致性,如:定义了一个模块的高度在 321 至 375下是40px,那么一个模块在这个范围的屏幕中显示就是40px,而不能随屏幕大小而变化。
方案三 flex布局
- 类似于百分比布局,无需计算百分比,可以很好的适配所有屏幕
手机天猫 典型的flex布局,flex做了很好的兼容处理,高度写死,可查看顶部搜索栏源码
缺点:
- 有着和百分比布局一样的缺点,高度不便调整
- 有几种不同的flex标准,在低端ios和安卓中有着各种各样的兼容性问题
方案四 使用rem单位
和上面的几种布局方案结合使用,主要做高度调整,保证布局一致
视口不缩放使用rem
手机网易为例
分析:
- 根据图片可以看出网易为750的设计稿,因为750下是html字体大小是100px,这样在切图时,方便px转rem,750设计稿上是大小是50px,那么转换成rem就是.5rem(如:24px -> .24rem);
- px转rem简单方便
- 没有做1px高清屏处理
- 未做图片高清处理
视口缩放下使用rem
手机淘宝为例
分析:
- 设计稿为750的设计稿
320 dpr=1 font-size=32px
320 dpr=2 font-size=64px
375 dpr=2 font-size=75px
414 dpr=3 font-size=124.2px
换算规则:(屏幕宽度 * dpr )/10 (除以10是为了将屏幕平分10份,为了将来替换成vm或vh单位) - 屏幕根据dpr的值进行了相应的缩放
- 很好的还原了1px在高清屏真实度
- 图片使用了750下的两倍图,并没有做按dpr的值加载不同的图片
- px转rem需要使用工具转换
字体适配
适配规则
段落文字在大屏上希望能看到更多文字,标题文字或字数固定的文字应该应用缩放原则,随屏幕变大而变化
视口不缩放
通过媒体查询去设置不同范围内的大小
视口缩放
根据不同的dpr值去设置相应字体大小
标题文字或长度固定的文字可以使用rem单位去做适配
1px边框
使用css hack解决
使用box-shadow
-webkit-box-shadow:0 1px 1px -1px rgba(0, 0, 0, 0.5); |
缺点:颜色不便控制,太淡,有虚边
使用background-image
background-image: |
缺点:不能实现圆角1px效果,css需要做兼容处理
使用border-image
border-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAECAYAAABP2FU6AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAB5JREFUeNpiPnH8zH/G////MzAxAAHTyRNn/wMEGABpvQm9g9TJ1QAAAABJRU5ErkJggg==") 2 0 stretch; |
缺点:边框颜色不便修改
伪类:after & transform: scale(0.5)
.box4 |
缺点:占用了伪类,容易和原样式冲突
使用0.5px适配ios8以上的iPhone机型
@media (-webkit-min-device-pixel-ratio:2){ |
缺点:只适用于ios8+以上的iOS系统,安卓机不支持0.5px
CodePen 示例:
See the Pen 1PX 的梗 by LT (@togglelt) on CodePen.
使用视口缩放
参考手淘方案(略)
阅读参考:
移动web点5像素的秘密
再谈mobile web retina 下 1px 边框解决方案
图片高清
视口不缩放:使用@2x两倍图
视口缩放:根据不同的dpr,加载不同尺寸的图片(图片处理服务器)
实践应用
npm install gulp-postcss postcss-px2rem –save-dev -d
处理px2rem
postcss-px2rem
.selector { |
.selector { |
CodePen 示例
See the Pen 移动端自适用布局测试 by LT (@togglelt) on CodePen.
hotcss和flexiable相同的方案
美丽说HIGO
奇虎360
爆米兔
新浪show
我理解的最佳实践
- 用户体验要求很高的页面,如UV较高的页面,活动页这些应该以用户体验优先,应用flexiable方案
- 在其它页面,固定视口,不缩放,使用rem做布局适配,js添加屏幕标识以便调整字体大小,使用@2x图片,只做ios8+的1px处理
阅读参考: