淘宝弹性布局方案lib-flexible研究
1. lib-flexible不能与响应式布局兼容
先说说响应式布局的一些基本认识:
响应式布局的表现是:网页通过css媒介查询判断可视区域的宽度,在不同的范围应用不同的样式,以便在不同尺寸的设备上呈现最佳的界面效果。典型的例子是,有一个商品列表页,应用响应式布局后,可能在pc上是用4列展示,在平板上用3列展示,在手机上只用1列展示。这种布局的最大好处就是节省人力、资源和时间,所以很多公司都喜欢用。而响应式布局有两个必须的要求:
1)是viewport的设置,width跟initial-scale要采用如下配置,保证viewport的宽度与device width相同:
+ View code
2)是要利用media query,针对不同的width范围,编写不同的css,比如bootstrap:
需要注意的是:第(1)个要求提到的device width与media query里面的device-width属性表达的意思有些区别:第(1)个要求提到的device width在移动设备下指的是设备的宽度,但是在pc下指的是浏览器可视区域的宽度,比如下面这个网页,我把浏览器窗口缩小,然后你看它viewport里尽管已经把width设置成了device-width,但是网页大小却不是我的桌面的分辨率宽度(设备宽度):
media query里的device-width属性,始终指的是设备的宽度。所以响应式布局的媒介查询要用width属性,不用device-width属性,因为在桌面设备下,把浏览器窗口缩小的时候,device-width并不会发生改变,当调整浏览器窗口大小就看不到响应式的效果。
再来看lib-flexible的特点:
lib-flexible在适配的时候会修改viewport的initial-scale,导致viewport的width不等于device width。这是采用lib-flexible,在iphone6 plus下适配后,自动添加的viewport设置代码:
在这个viewport的作用下,网页的缩放系数为0.3333333333333333,iphone6 plus的device width为414个不缩放的css像素,经过缩放之后,viewport的width等于device width / 0.3333333333333333,为1242个缩放后的css像素,远远大于device width:
假如你的网页想同时使用响应式布局和lib-flexible,然后你写了一个媒介查询,需要在1024px以上的分辨率(桌面设备)呈现某个特殊样式(代码仅仅是为了举例):
会发现这个页面在iphone6 plus下也会应用到该媒介查询的样式:
究其原因是:iphone6 plus下的网页由于lib-flexible的作用,导致页面的width与实际物理分辨率的宽相等,也就是1242个像素,完全达到了该媒介查询的范围。
所以,在使用lib-flexible的项目里很难再实现响应式布局,要是有人有这种综合两者一起使用的想法,可得注意了。实际上,这两个方案本质性的东西就不相同,适用的场景也不相同。响应式布局的目的是一套代码,能够在手机平板和pc上都能良好展现,适用于网站类的项目,而lib-flexible解决的是手机端网页的适配问题,压根不管平板和pc的情况,适用于web app类的项目。
2. 1px边框在lib-flexible下如何处理
web app有时候会设计出一些特别细的线条或者边框,如果我们直接通过css设置边框为1px:
结果会发现这种边框在手机里看起来的效果,显得特别地粗,之所以会有这个效果,原因很简单,因为现在大部分手机的分辨率很高,一个css像素,比如上面代码中的1px,可能相当于2个甚至3个物理分辨率像素,而不像pc,一个css像素始终等于1个物理分辨率像素,所以手机里看到的1px会比实际的粗。
为了解决这个问题,你可能会想到用0.5px来代替1px,不过这个是解决不了问题的,而且带小数的像素在不同的浏览器下绝对是一个坑,千万要尽量避免。
那么通常在web app下显示1px的做法是怎样的呢,前阵子在weui的源码中看到了一个很好的办法,值得分享:
这个办法并不是利用border属性来显示边框,而是利用了伪类和transform,最妙的是这个transform,0.5px办不到的事情,它却办得到。
由于lib-flexible在适配的时候,会缩放网页,导致css代码中的1px等于物理分辨率的1px,这样子这个1px边框的问题在经过lib-flexible适配的设备下就很好解决了,直接应用border: 1px solid;即可。但是lib-flexible现在只适配了iphone设备,安卓设备压根没适配:
导致在安卓设备下,1px的边框问题依然存在。所以为了在lib-flexible的项目里解决1px的问题,就得综合两种做法了:
+ View code
这个做法,我做过测试,在我devicePixelRatio为3的meilan note上,显示出的线条非常细腻,看起来很舒服,iphone的效果也不错,借别人的机子测试过,所以有兴趣的人可以借鉴使用,有问题尽管提出,看看能不能有更好的办法解决。这是我用魅蓝note做测试的截图:
第1根线是上面的mixin效果;第二根线是直接使用border: 1px solid的效果。
注:以上提到的这个1px边框的做法有三个缺点,在使用的时候需要注意:
1)它会占用掉before伪类
2)没法做圆角
3)很难实现多条边框,除非嵌套,或者再利用上after伪类。
尽管如此,以上这个做法还是非常有用的做法,因为这种细线边框属于比较特殊的设计要求,并不是每处边框都得做成这样,在开发webapp的时候用这个方法保证特殊线条的设计要求,其它的边线,我觉得直接用border并没有关系,你可以直接用你的手机打开bootstrap的官方页面,看它里面的按钮边框,效果都还不错。
3. lib-flexible如何处理retina屏下的background-image
几年之前,retina屏,也就是所谓的高清屏,还不像现在这么普遍,12年我买的第一个安卓机是华为u8825d,分辨率只有480*800,而且当时市面上大部分安卓机基本上都是这个分辨率,像iphone4 那种640*960级别的机子很少,为了解决普通背景图片在iphone4下显示模糊的问题,基本都是采用这种做法:
估计当时应该是320的设计稿,img_1x.png是在320设计稿下切出的图,然后img_2x.png是在320设计稿矢量放大2倍后切出的图,高清屏显示img_2x.png,这样就能解决当时iphone4背景图片模糊的问题。
时至今日,手机都是走高配置,低价格的发展路线,480*800这种级别的机子,市面上越来越少,大部分手机的分辨率级别都达到了iphone4的标准,比iphone4的清晰级别更高的手机也越来越多,一个800块的魅蓝note,它的devicePixelRatio都已经达到了3,原先解决background-image问题的方法,需要调整一下才能适用于现在:
代码中的2x和3x是相当于320的设计稿而言的,2x代替了原先的1x,3x代替了原先的2x。现在的设计稿也不再是320,而是640,2x就是在640下切出的图,3x是在640基础上矢量放大1.5切出的图。在这个代码的作用下,分辨率在640以下的设备都会显示2x的图,由于2x的图本身是在640的设计稿切出的,所以这些设备下不会有模糊的现象,在640以上的分辨率,会显示3x的图,由于3x的图是在960的分辨率下切出的,所以这种图在分辨率小于960的设备下都不会模糊。以前1x的情况根本不用再考虑了,以后不会再有需要1x图的设备,说不定过几年,市面上的手机全是devicePixelRatio在2.5以上的标准时,连2x的情况也不用考虑了。
lib-flexible在iphone6推出之后,把设计稿的尺寸提高到了750,切图时还是按2x和3x的方法来切,这样的话,经过lib-flexible适配的设备,分辨率在750以下都会显示2x的图,肯定不会模糊;分辨率在750以上的设备,会显示3x的图,也不会出现模糊。不过由于lib-flexible只适配了iphone的问题,所以我上篇博客中提到的用data-dpr来显示不同的图片的做法是错误的,因为有些安卓机,比如我的魅族node,devicePixelRatio是3,打开app页面,看到的图片却仍然还是2x的,显然达不到适配的要求,所以不能用data-dpr去适配,而应该采用下面这个做法:
这个代码的最终效果是:
1)devicePixelRatio大于等于2.5的设备都会应用到3x图
2)其它设备都会应用到2x的图。
这个方法,在chrome的模拟器里测试过很多机型,效果不错,不过它只适用于不使用雪碧图的背景图片,如果要在lib-flexible的项目里使用雪碧图作背景图片,同时又要考虑retina屏的话,需要将上面这个方法稍微改动一下。
首先看下不使用lib-flexible时,雪碧图背景在retina下是怎么做的,以腾讯的一个活动页面来说明http://qzs.qq.com/qzone/qzact/act/qzapp/qzone5.0/mobile/index.html,这是它在使用1x的雪碧图时某个元素的background的样式:
这是它在使用2x的雪碧图时某个元素的background的样式:
总结下它这个做法:
1)先把设计稿切出的图,合并成一张雪碧图,腾讯这个例子的设计稿是320的,所以它的切图都是1x的,这张雪碧图也就是1x的,大小为643 * 152
2)设计稿放大2倍,切图合并成一张2x的雪碧图,大小为1286 * 304
3)普清屏下只应用background-image和background-position属性,设置1x雪碧图作为背景,代码参考截图
4)高清屏下除了应用background-image和background-position属性,还要应用background-size属性,并且这个background-size的大小要设置为1x雪碧图的大小,background-position的值要与(3)里配置的值相同,代码参考截图。
如果把它做成一个mixin的话应该是类似这样的:
考虑到1x不会再有的情况,上面这个mixin可以再调整一下:
默认用2x的图,devicePixelRatio大于等于2.5的设备用3x的图。这个调整后的mixin就是lib-flexible下,使用雪碧图背景的方法,应用举例:
sprite.png用750设计稿的切图合并后的大小是414 * 232,.btn-android这个按钮的position为0 –64px。
尽管这个方法看起来完美,但是不建议使用,因为它的适配效果不好,这是iphone6下的效果:
看起来不错,那是当然的,因为这就是它默认没有任何缩放的效果。然后看iphone6 plus的效果:
有点差异,但好像还能接受。再看看nexus6的效果:
这就不能忍了,样式差的离谱。造成这个差异的原因也很简单,就是rem的副作用,腾讯的页面里所有position,size都是不带小数的数值,而且2x跟1x之间是整数的翻倍,而不是3x跟2x之间的1.5倍,lib-flexible会导致大部分的设备下position和size都是小数数值,所以很难保证背景图片缩放后还能通过position显示到正确的位置:
从网页优化的角度来说,减少请求数,减少请求数据大小是两个基本的思路,雪碧图就是一个减少请求数但是不能减少请求数据量的方法。lib-flexible不能使用兼容3x屏的雪碧图的情况看起来是它一个大的缺陷,但实际上也并非如此:雪碧图如果用不了,就采用别的思路来优化,我能想到的更好的就是图片的延迟加载和懒加载,在app页面里控制好默认只加载首屏的图片,并且采用延迟和懒加载的方式,避免阻塞页面的加载,也能有极好的用户体验,打开手机淘宝的页面给人的感觉就是如此,而且你去看看手机淘宝的应用会发现它根本就没有用雪碧图,但是速度还是很快。
淘宝弹性布局方案lib-flexible研究的更多相关文章
- 基于淘宝弹性布局方案lib-flexible的问题研究
上篇文章<淘宝弹性布局方案lib-flexible实践>结合一个简单的实例,说明了lib-flexible的基本用法,但是lib-flexible的这种适配方式在适配的时候会修改viewp ...
- 淘宝弹性布局方案lib-flexible实践
2个月前,写过一篇文章<从网易与淘宝的font-size思考前端设计稿与工作流>总结过一些移动web中有关手机适配的一些思路,当时也是因为工作的关系分析了下网易跟淘宝的移动页面,最后才有那 ...
- 妈妈再也不用担心我的移动端了:网易和淘宝的rem方案剖析
从博主学习前端一路过来的经历了解到,前端移动开发是大部分从PC端转战移动端的小伙伴都非常头疼的一个问题,这边博主就根据一篇自己看过的移动开发文章来剖析一下网易和淘宝的rem解决方案,希望能够帮助到一些 ...
- 网易和淘宝的rem方案剖析
以下内容到分割线前是引用前端大牛的文章,方便大家理解博主内容): 从网易与淘宝的font-size思考前端设计稿与工作流 1. 简单问题简单解决 我觉得有些web app并一定很复杂,比如拉勾网,你看 ...
- 关于http和https淘宝支付宝跨域解决方法研究
关于http和http跨域淘宝解决方式研究: http://buyer.trade.taobao.com/trade/pay.htm?spm=a1z01.2.3.4.0.wZAGp9&bizO ...
- 淘宝双十一页面(Flexible)demo
下面的代码是看了大漠 使用Flexible实现手淘H5页面的终端适配 做的一个demo. <!DOCTYPE html> <html lang="en" ng-a ...
- 淘宝双十一页面(Flexible)
以下demo点我下载 <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...
- 淘宝rem适配方案
/*px 转化换 rem ,转化是 10 .比如:你的设计图为750,那么就 750 / 75 = 10 rem.设计图中你量尺寸都要除 75 就是 rem值.再比如量的设计图按钮宽度 66px,那么 ...
- 仿淘宝使用flex布局实现页面顶部和底部的固定布局
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...
随机推荐
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6703247 上文介绍了Android应用程序的 ...
- Qt使用异或进行加密解密
在加密,解密中,异或运算应该时比较简单的一种.下面的代码,采用异或运算进行加密,解密: 点击(此处)折叠或打开 #include <QtCore/QCoreApplication&g ...
- kaggle之手写体识别
kaggle地址 数据预览 首先载入数据集 import pandas as pd import numpy as np train = pd.read_csv('/Users/frank/Docum ...
- zabbix PHP databases support off Fail
zabbix初始化检查安装环境不通过: PHP databases support off Fail --未找到所支持的数据库 处理方法:安装Mysqli模块 ############## ...
- HTML基础知识笔记(一)
HTML定义 HTML指的是超文本标记语言 HTML不是编程语言,而是标记语言 标记语言是一套标记标签 HTML是用标记标签来描述网页 HTML标签1 <html></html& ...
- H5移动端性能优化
概述 1. PC优化手段在Mobile侧同样适用 2. 在Mobile侧我们提出三秒种渲染完成首屏指标 3. 基于第二点,首屏加载3秒完成或使用Loading 4. 基于联通3G网络平均338KB/s ...
- HTML - Textarea - 空格的问题解决方式
第一种方式: <textarea name="textareaname" rows="XX" cols="XX" ></t ...
- 一、Autofac入门
想要将autofac集成到你的应用程序中需要经过如下步骤: 1.使用控制翻转(IoC)的思想架构你的应用程序: 2.添加autofac引用: 3.在应用程序入口...(At application s ...
- C#实现在线更新系统
先来看一下程序完成后长什么样. 这个是程序的组成部分. 主要功能是在InitializationUpdate这个类中完成的,From1主要起到调用的作用,所以重心还是在InitializationUp ...
- 关于很简单的设计模式,ui-dao-database,以及JavaBean和util工具类
关于很简单的设计模式,ui-dao-database,以及JavaBean和util工具类 24. 三 / J2EE / 没有评论 简单的j2ee设计模式, UI通过DAO层访问数据库或者xml文 ...