本文的內容就是介紹淘寶彈性布局方案lib-flexible實踐,
原理是通過js事實的檢測屏幕的大小並改變html標簽的字體大小,再結合rem的特性來完成頁面的自適應。下面是flexible作者的說明。
https://github.com/amfe/article/issues/17
分享給大家供大家參考,具體內容如下
1. 頁面需求
這是要做的頁面效果(不要對設計置評,這不是開發人員決定的):

這是尺寸標注圖(750*1334):

然后美工在750*1334的設計稿之上,按我的要求提供以下素材的切圖:

包括兩個下載按鈕的背景圖片,logo,底部梯形的漸變背景和body部分的mobile 背景圖。注意這些圖片都是在750*1334的設計稿里面切出來的,所以尺寸都是設計稿里的原始尺寸,比如android.png:

考慮到retina顯示屏的問題,結合下圖的適配思路:

我認為解決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下的圖片,還是以安卓下載按鈕的樣式為例,寫法是: