flexible.js 淘宝弹性布局方案

本文的内容就是介绍淘宝弹性布局方案lib-flexible实践,css

原理是经过js事实的检测屏幕的大小并改变html标签的字体大小,再结合rem的特性来完成页面的自适应。下面是flexible做者的说明。html

https://github.com/amfe/article/issues/17android

分享给你们供你们参考,具体内容以下git

1. 页面需求github

这是要作的页面效果(不要对设计置评,这不是开发人员决定的):chrome

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

这是尺寸标注图(750*1334):iphone

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

而后美工在750*1334的设计稿之上,按个人要求提供如下素材的切图:布局

 

 

 

 

包括两个下载按钮的背景图片,logo,底部梯形的渐变背景和body部分的mobile 背景图。注意这些图片都是在750*1334的设计稿里面切出来的,因此尺寸都是设计稿里的原始尺寸,好比android.png:字体

 

 

 

 

 

 

 

 

 

 

考虑到retina显示屏的问题,结合下图的适配思路:flex

 

 

 

 

 

 

 

 

 

 

 

 

 

 

我认为解决retina屏问题的可行方案是:

1)在devicePixelRatio<=2时,图片统一使用750设计稿的切图

2)在devicePixelRatio>=2时,图片统一使用750*1.5=1125,也就是所谓@3x设计稿的切图。

我把美工给个人在750*1334的设计稿下的切图都放在img/@2x 这个文件夹下:

 

 

 

 

 

而后让她帮忙把750的设计稿矢量放大1.5倍,再按照一样的切图要求为我提供@3x的切图,并放在了img/@3x 这个文件夹下:

 

 

 

 

 

@3x下的图片理论上尺寸应该等于@2x下的图片*1.5,不过个人切的没有这么完美。

有了前面的需求介绍和素材准备,下一步就是该引入核心的js文件,编写css样式了。

2. 引入flexible.js

这一步其实很是简单,只要把flexible.js的内容复制出来,在本地新建一个flexible.js的文件,打开粘贴进去就能够了,我把这个文件放在了js/lib下面:

 

 

 

 

 

接着在html页面里面,尽量早的引入这个js文件(为了让适配的效果更快):

 

 

 

 

 

注:使用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了:

 

 

 

 

 

 

3. 编写CSS
基本要求:

1)除font-size外,其它大小都根据750标注稿的尺寸,转换成rem单位的值,转换方法为:标注稿尺寸 / 标注稿基准字体大小;例如模拟器中html的字体大小显示位64px,设计稿的高度为60px(设计稿宽度640px),那么这个rem的职位60/64

2)标注稿基准字体大小 = 标注稿宽度 / 10,如标注稿宽为750,标注稿基准字体大小为75;标注稿宽为640,标注稿基准字体大小为64;(因此淘宝这个方案是能够在任意设计稿尺寸下使用的

3)若是须要设置font-size,可跟据html的data-dpr属性来处理:

   在做者的观点中,是建议描述性的字体使用px,若是有slogan之类大于48px的,可使用rem,因为使用rem在iPhone5和iPhone6中字体不一样,可能出现13px和15px,点阵字体。显然,咱们在iPhone3G和iPhone4的Retina屏下面,但愿看到的文本字号是相同的。也就是说,咱们不但愿文本在Retina屏幕下变小,另外,咱们但愿在大屏手机上看到更多文本,以及,如今绝大多数的字体文件都自带一些点阵尺寸,一般是16px和24px,因此咱们不但愿出现13px和15px这样的奇葩尺寸。如此一来,就决定了在制做H5的页面中,rem并不适合用到段落文本上。因此在Flexible整个适配方案中,考虑文本仍是使用px做为单位。只不过使用[data-dpr]属性来区分不一样dpr下的文本字号大小。
div {
        width: 1rem;
        height: 0.4rem;
        font-size: 12px; // 默认写上dpr为1的fontSize
    }
    [data-dpr="2"] div {
        font-size: 24px;
    }
    [data-dpr="3"] div {
        font-size: 36px;
    }

为了能更好的利于开发,在实际开发中,咱们能够定制一个font-dpr()这样的Sass混合宏:

@mixin font-dpr($font-size){
        font-size: $font-size;

        [data-dpr="2"] & {
            font-size: $font-size * 2;
        }

        [data-dpr="3"] & {
            font-size: $font-size * 3;
        }
    }

有了这样的混合宏以后,在开发中能够直接这样使用:

@include font-dpr(16px);


固然这只是针对于描述性的文本,好比说段落文本。但有的时候文本的字号也须要分场景的,好比在项目中有一个slogan,业务方但愿这个slogan能根据不一样的终端适配。针对这样的场景,彻底可使用rem给slogan作计量单位。

 

到此,lib-flexible的基本实践就结束了,不过还有一个问题,就是retina屏的问题,到如今都还没提到@3x下图的那些切图怎么办, 其实很简单,借助html元素的data-dpr属性,能够轻松实现另外一种媒介查询,以便在devicePixelRatio>=2的时候启用 @3x下的图片,仍是以安卓下载按钮的样式为例,写法是:

.btn-android {
 background-image: url("../img/@2x/android.png?v=@@version");
 [data-dpr="3"] & {
  background-image: url("../img/@3x/android.png?v=@@version");
 }
}