淘宝弹性布局方案lib-flexible研究
1. lib-flexible不能與響應(yīng)式布局兼容
先說說響應(yīng)式布局的一些基本認(rèn)識(shí):
響應(yīng)式布局的表現(xiàn)是:網(wǎng)頁通過css媒介查詢判斷可視區(qū)域的寬度,在不同的范圍應(yīng)用不同的樣式,以便在不同尺寸的設(shè)備上呈現(xiàn)最佳的界面效果。典型的例子是,有一個(gè)商品列表頁,應(yīng)用響應(yīng)式布局后,可能在pc上是用4列展示,在平板上用3列展示,在手機(jī)上只用1列展示。這種布局的最大好處就是節(jié)省人力、資源和時(shí)間,所以很多公司都喜歡用。而響應(yīng)式布局有兩個(gè)必須的要求:
1)是viewport的設(shè)置,width跟initial-scale要采用如下配置,保證viewport的寬度與device width相同:
+ View code2)是要利用media query,針對(duì)不同的width范圍,編寫不同的css,比如bootstrap:
+ View code需要注意的是:第(1)個(gè)要求提到的device width與media query里面的device-width屬性表達(dá)的意思有些區(qū)別:第(1)個(gè)要求提到的device width在移動(dòng)設(shè)備下指的是設(shè)備的寬度,但是在pc下指的是瀏覽器可視區(qū)域的寬度,比如下面這個(gè)網(wǎng)頁,我把瀏覽器窗口縮小,然后你看它viewport里盡管已經(jīng)把width設(shè)置成了device-width,但是網(wǎng)頁大小卻不是我的桌面的分辨率寬度(設(shè)備寬度):
media query里的device-width屬性,始終指的是設(shè)備的寬度。所以響應(yīng)式布局的媒介查詢要用width屬性,不用device-width屬性,因?yàn)樵谧烂嬖O(shè)備下,把瀏覽器窗口縮小的時(shí)候,device-width并不會(huì)發(fā)生改變,當(dāng)調(diào)整瀏覽器窗口大小就看不到響應(yīng)式的效果。
再來看lib-flexible的特點(diǎn):
lib-flexible在適配的時(shí)候會(huì)修改viewport的initial-scale,導(dǎo)致viewport的width不等于device width。這是采用lib-flexible,在iphone6 plus下適配后,自動(dòng)添加的viewport設(shè)置代碼:
+ View code在這個(gè)viewport的作用下,網(wǎng)頁的縮放系數(shù)為0.3333333333333333,iphone6 plus的device width為414個(gè)不縮放的css像素,經(jīng)過縮放之后,viewport的width等于device width / 0.3333333333333333,為1242個(gè)縮放后的css像素,遠(yuǎn)遠(yuǎn)大于device width:
假如你的網(wǎng)頁想同時(shí)使用響應(yīng)式布局和lib-flexible,然后你寫了一個(gè)媒介查詢,需要在1024px以上的分辨率(桌面設(shè)備)呈現(xiàn)某個(gè)特殊樣式(代碼僅僅是為了舉例):
+ View code會(huì)發(fā)現(xiàn)這個(gè)頁面在iphone6 plus下也會(huì)應(yīng)用到該媒介查詢的樣式:
究其原因是:iphone6 plus下的網(wǎng)頁由于lib-flexible的作用,導(dǎo)致頁面的width與實(shí)際物理分辨率的寬相等,也就是1242個(gè)像素,完全達(dá)到了該媒介查詢的范圍。
所以,在使用lib-flexible的項(xiàng)目里很難再實(shí)現(xiàn)響應(yīng)式布局,要是有人有這種綜合兩者一起使用的想法,可得注意了。實(shí)際上,這兩個(gè)方案本質(zhì)性的東西就不相同,適用的場(chǎng)景也不相同。響應(yīng)式布局的目的是一套代碼,能夠在手機(jī)平板和pc上都能良好展現(xiàn),適用于網(wǎng)站類的項(xiàng)目,而lib-flexible解決的是手機(jī)端網(wǎng)頁的適配問題,壓根不管平板和pc的情況,適用于web app類的項(xiàng)目。
2. 1px邊框在lib-flexible下如何處理
web app有時(shí)候會(huì)設(shè)計(jì)出一些特別細(xì)的線條或者邊框,如果我們直接通過css設(shè)置邊框?yàn)?px:
+ View code結(jié)果會(huì)發(fā)現(xiàn)這種邊框在手機(jī)里看起來的效果,顯得特別地粗,之所以會(huì)有這個(gè)效果,原因很簡單,因?yàn)楝F(xiàn)在大部分手機(jī)的分辨率很高,一個(gè)css像素,比如上面代碼中的1px,可能相當(dāng)于2個(gè)甚至3個(gè)物理分辨率像素,而不像pc,一個(gè)css像素始終等于1個(gè)物理分辨率像素,所以手機(jī)里看到的1px會(huì)比實(shí)際的粗。
為了解決這個(gè)問題,你可能會(huì)想到用0.5px來代替1px,不過這個(gè)是解決不了問題的,而且?guī)?shù)的像素在不同的瀏覽器下絕對(duì)是一個(gè)坑,千萬要盡量避免。
那么通常在web app下顯示1px的做法是怎樣的呢,前陣子在weui的源碼中看到了一個(gè)很好的辦法,值得分享:
+ View code這個(gè)辦法并不是利用border屬性來顯示邊框,而是利用了偽類和transform,最妙的是這個(gè)transform,0.5px辦不到的事情,它卻辦得到。
由于lib-flexible在適配的時(shí)候,會(huì)縮放網(wǎng)頁,導(dǎo)致css代碼中的1px等于物理分辨率的1px,這樣子這個(gè)1px邊框的問題在經(jīng)過lib-flexible適配的設(shè)備下就很好解決了,直接應(yīng)用border: 1px solid;即可。但是lib-flexible現(xiàn)在只適配了iphone設(shè)備,安卓設(shè)備壓根沒適配:
導(dǎo)致在安卓設(shè)備下,1px的邊框問題依然存在。所以為了在lib-flexible的項(xiàng)目里解決1px的問題,就得綜合兩種做法了:
+ View code這個(gè)做法,我做過測(cè)試,在我devicePixelRatio為3的meilan note上,顯示出的線條非常細(xì)膩,看起來很舒服,iphone的效果也不錯(cuò),借別人的機(jī)子測(cè)試過,所以有興趣的人可以借鑒使用,有問題盡管提出,看看能不能有更好的辦法解決。這是我用魅藍(lán)note做測(cè)試的截圖:
第1根線是上面的mixin效果;第二根線是直接使用border: 1px solid的效果。
注:以上提到的這個(gè)1px邊框的做法有三個(gè)缺點(diǎn),在使用的時(shí)候需要注意:
1)它會(huì)占用掉before偽類
2)沒法做圓角
3)很難實(shí)現(xiàn)多條邊框,除非嵌套,或者再利用上after偽類。
盡管如此,以上這個(gè)做法還是非常有用的做法,因?yàn)檫@種細(xì)線邊框?qū)儆诒容^特殊的設(shè)計(jì)要求,并不是每處邊框都得做成這樣,在開發(fā)webapp的時(shí)候用這個(gè)方法保證特殊線條的設(shè)計(jì)要求,其它的邊線,我覺得直接用border并沒有關(guān)系,你可以直接用你的手機(jī)打開bootstrap的官方頁面,看它里面的按鈕邊框,效果都還不錯(cuò)。
3. lib-flexible如何處理retina屏下的background-image
幾年之前,retina屏,也就是所謂的高清屏,還不像現(xiàn)在這么普遍,12年我買的第一個(gè)安卓機(jī)是華為u8825d,分辨率只有480*800,而且當(dāng)時(shí)市面上大部分安卓機(jī)基本上都是這個(gè)分辨率,像iphone4 那種640*960級(jí)別的機(jī)子很少,為了解決普通背景圖片在iphone4下顯示模糊的問題,基本都是采用這種做法:
+ View code估計(jì)當(dāng)時(shí)應(yīng)該是320的設(shè)計(jì)稿,img_1x.png是在320設(shè)計(jì)稿下切出的圖,然后img_2x.png是在320設(shè)計(jì)稿矢量放大2倍后切出的圖,高清屏顯示img_2x.png,這樣就能解決當(dāng)時(shí)iphone4背景圖片模糊的問題。
時(shí)至今日,手機(jī)都是走高配置,低價(jià)格的發(fā)展路線,480*800這種級(jí)別的機(jī)子,市面上越來越少,大部分手機(jī)的分辨率級(jí)別都達(dá)到了iphone4的標(biāo)準(zhǔn),比iphone4的清晰級(jí)別更高的手機(jī)也越來越多,一個(gè)800塊的魅藍(lán)note,它的devicePixelRatio都已經(jīng)達(dá)到了3,原先解決background-image問題的方法,需要調(diào)整一下才能適用于現(xiàn)在:
+ View code代碼中的2x和3x是相當(dāng)于320的設(shè)計(jì)稿而言的,2x代替了原先的1x,3x代替了原先的2x。現(xiàn)在的設(shè)計(jì)稿也不再是320,而是640,2x就是在640下切出的圖,3x是在640基礎(chǔ)上矢量放大1.5切出的圖。在這個(gè)代碼的作用下,分辨率在640以下的設(shè)備都會(huì)顯示2x的圖,由于2x的圖本身是在640的設(shè)計(jì)稿切出的,所以這些設(shè)備下不會(huì)有模糊的現(xiàn)象,在640以上的分辨率,會(huì)顯示3x的圖,由于3x的圖是在960的分辨率下切出的,所以這種圖在分辨率小于960的設(shè)備下都不會(huì)模糊。以前1x的情況根本不用再考慮了,以后不會(huì)再有需要1x圖的設(shè)備,說不定過幾年,市面上的手機(jī)全是devicePixelRatio在2.5以上的標(biāo)準(zhǔn)時(shí),連2x的情況也不用考慮了。
lib-flexible在iphone6推出之后,把設(shè)計(jì)稿的尺寸提高到了750,切圖時(shí)還是按2x和3x的方法來切,這樣的話,經(jīng)過lib-flexible適配的設(shè)備,分辨率在750以下都會(huì)顯示2x的圖,肯定不會(huì)模糊;分辨率在750以上的設(shè)備,會(huì)顯示3x的圖,也不會(huì)出現(xiàn)模糊。不過由于lib-flexible只適配了iphone的問題,所以我上篇博客中提到的用data-dpr來顯示不同的圖片的做法是錯(cuò)誤的,因?yàn)橛行┌沧繖C(jī),比如我的魅族node,devicePixelRatio是3,打開app頁面,看到的圖片卻仍然還是2x的,顯然達(dá)不到適配的要求,所以不能用data-dpr去適配,而應(yīng)該采用下面這個(gè)做法:
+ View code這個(gè)代碼的最終效果是:
1)devicePixelRatio大于等于2.5的設(shè)備都會(huì)應(yīng)用到3x圖
2)其它設(shè)備都會(huì)應(yīng)用到2x的圖。
這個(gè)方法,在chrome的模擬器里測(cè)試過很多機(jī)型,效果不錯(cuò),不過它只適用于不使用雪碧圖的背景圖片,如果要在lib-flexible的項(xiàng)目里使用雪碧圖作背景圖片,同時(shí)又要考慮retina屏的話,需要將上面這個(gè)方法稍微改動(dòng)一下。
首先看下不使用lib-flexible時(shí),雪碧圖背景在retina下是怎么做的,以騰訊的一個(gè)活動(dòng)頁面來說明http://qzs.qq.com/qzone/qzact/act/qzapp/qzone5.0/mobile/index.html,這是它在使用1x的雪碧圖時(shí)某個(gè)元素的background的樣式:
這是它在使用2x的雪碧圖時(shí)某個(gè)元素的background的樣式:
總結(jié)下它這個(gè)做法:
1)先把設(shè)計(jì)稿切出的圖,合并成一張雪碧圖,騰訊這個(gè)例子的設(shè)計(jì)稿是320的,所以它的切圖都是1x的,這張雪碧圖也就是1x的,大小為643 * 152
2)設(shè)計(jì)稿放大2倍,切圖合并成一張2x的雪碧圖,大小為1286 * 304
3)普清屏下只應(yīng)用background-image和background-position屬性,設(shè)置1x雪碧圖作為背景,代碼參考截圖
4)高清屏下除了應(yīng)用background-image和background-position屬性,還要應(yīng)用background-size屬性,并且這個(gè)background-size的大小要設(shè)置為1x雪碧圖的大小,background-position的值要與(3)里配置的值相同,代碼參考截圖。
如果把它做成一個(gè)mixin的話應(yīng)該是類似這樣的:
+ View code考慮到1x不會(huì)再有的情況,上面這個(gè)mixin可以再調(diào)整一下:
+ View code默認(rèn)用2x的圖,devicePixelRatio大于等于2.5的設(shè)備用3x的圖。這個(gè)調(diào)整后的mixin就是lib-flexible下,使用雪碧圖背景的方法,應(yīng)用舉例:
+ View codesprite.png用750設(shè)計(jì)稿的切圖合并后的大小是414 * 232,.btn-android這個(gè)按鈕的position為0 –64px。
盡管這個(gè)方法看起來完美,但是不建議使用,因?yàn)樗倪m配效果不好,這是iphone6下的效果:
看起來不錯(cuò),那是當(dāng)然的,因?yàn)檫@就是它默認(rèn)沒有任何縮放的效果。然后看iphone6 plus的效果:
有點(diǎn)差異,但好像還能接受。再看看nexus6的效果:
這就不能忍了,樣式差的離譜。造成這個(gè)差異的原因也很簡單,就是rem的副作用,騰訊的頁面里所有position,size都是不帶小數(shù)的數(shù)值,而且2x跟1x之間是整數(shù)的翻倍,而不是3x跟2x之間的1.5倍,lib-flexible會(huì)導(dǎo)致大部分的設(shè)備下position和size都是小數(shù)數(shù)值,所以很難保證背景圖片縮放后還能通過position顯示到正確的位置:
從網(wǎng)頁優(yōu)化的角度來說,減少請(qǐng)求數(shù),減少請(qǐng)求數(shù)據(jù)大小是兩個(gè)基本的思路,雪碧圖就是一個(gè)減少請(qǐng)求數(shù)但是不能減少請(qǐng)求數(shù)據(jù)量的方法。lib-flexible不能使用兼容3x屏的雪碧圖的情況看起來是它一個(gè)大的缺陷,但實(shí)際上也并非如此:雪碧圖如果用不了,就采用別的思路來優(yōu)化,我能想到的更好的就是圖片的延遲加載和懶加載,在app頁面里控制好默認(rèn)只加載首屏的圖片,并且采用延遲和懶加載的方式,避免阻塞頁面的加載,也能有極好的用戶體驗(yàn),打開手機(jī)淘寶的頁面給人的感覺就是如此,而且你去看看手機(jī)淘寶的應(yīng)用會(huì)發(fā)現(xiàn)它根本就沒有用雪碧圖,但是速度還是很快。
轉(zhuǎn)載于:https://www.cnblogs.com/axl234/p/5809086.html
總結(jié)
以上是生活随笔為你收集整理的淘宝弹性布局方案lib-flexible研究的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何通过Maven的Tomcat插件运行
- 下一篇: c多线程