Flexible到今天也有幾年的歷史了,解救了不少同窗針對於H5頁面佈局的適配問題。而這套方案也相對而言是一個較爲成熟的方案。簡單的回憶一下,當初爲了能讓頁面更好的適配各類不一樣的終端,經過Hack手段來根據設備的dpr
值相應改變<meta>
標籤中viewport
的值:css
從而讓頁面達麼縮放的效果,也變相的實現頁面的適配功能。而其主要的思想有三點:html
dpr
的值來修改viewport
實現1px
的線dpr
的值來修改html
的font-size
,從而使用rem
實現等比縮放rem
模擬vw
特性有關於Flexible方案實現適配,在2015年雙十一以後作過這方面的技術文檔分享,感興趣的同窗能夠移步閱讀《使用Flexible實現手淘H5頁面的終端適配》一文。雖然Flexible解決了適配終端不少問題,但它並非萬能的,也不是最優秀的,他仍是存在一些問題的,好比iframe
的引用,有時候就把咱們本身給埋進去了。針對其中的一些不足之處,有些同窗對其進行過相關的改造,在網上搜索能找到相關的方案。前端
那麼時代在變化,前端技術在不斷的變化,試問:Flexible仍是最佳方案?Flexible還有存在的必要嗎? 最近一直在探討這方面,這裏先告訴你們Flexible已經完成了他自身的歷史使命,咱們能夠放下Flexible,擁抱新的變化。接下來的內容,我將分享一下我最近本身探討的新的適配方案,或許不少團隊同窗已經開始使用了,若是有不對之處,但願能獲得大嬸們的指正;若是您有更好的方案,但願能一塊兒分享一塊兒探討。html5
先上個二維碼:ios
你可使用手淘App、優酷APP、各終端自帶的瀏覽器、UC瀏覽器、QQ瀏覽器、Safari瀏覽器和Chrome瀏覽器掃描上面的二維碼,您看到相應的效果:css3
iPhone系列效果git
部分Android效果github
注:若是掃上面的二維碼沒有任何效果,你能夠點擊這裏,打開在線頁面,從新生成你的設備能識別的二維碼號 。瀏覽器
上面的Demo,測試了Top30的機型。目前未獲得支持的:svg
品牌 | 型號 | 系統版本 | 分辨率 | 屏幕尺寸 | 手淘APP | 優酷APP | 原生瀏覽器 | QQ瀏覽器 | UC瀏覽器 | Chrome瀏覽器 |
---|---|---|---|---|---|---|---|---|---|---|
華爲 | Mate9 | Android7.0 | 1080 x 1920 | 5英寸 | Yes | Yes | No | Yes | Yes | Yes |
華爲 | Mate7 | Android4.2 | 1080 x 1920 | 5.2英寸 | Yes | Yes | No | Yes | Yes | Yes |
魅族 | Mx4 (M460 移動4G) | Android4.4.2 | 1152 x 1920 | 5.36英寸 | Yes | No | No | Yes | Yes | Yes |
Oppo | R7007 | Android4.3 | 1280 x 720 | 5英寸 | Yes | No | No | Yes | Yes | No |
三星 | N9008 (Galaxy Note3) | Android4.4.2 | 1080 x 1920 | 5.7英寸 | Yes | No | Yes | Yes | Yes | Yes |
華碩 | ZenFone5(x86) | Android4.3 | 720 x 280 | 5英寸 | No | No | No | Yes | No | No |
Top30機型中不在列表中的,將看到的效果如上圖所示。至於敢不敢用,這就得看親了。必竟第一個吃螃蟹的人是須要必定的勇氣!(^_^)
前面給你們介紹了這個方案目前獲得的支持狀況以及效果。也扯了很多廢話,接下來進入正題吧。
在移動端佈局,咱們須要面對兩個最爲重要的問題:
不一樣的終端,咱們面對的屏幕分辨率、DPR、1px
、2x
圖等一系列的問題。那麼這個佈局方案也是針對性的解決這些問題,只不過解決這些問題再也不是使用Hack手段來處理,而是直接使用原生的CSS技術來處理的。
首要解決的是適配終端。回想一下,之前的Flexible方案是經過JavaScript來模擬vw
的特性,那麼到今天爲止,vw
已經獲得了衆多瀏覽器的支持,也就是說,能夠直接考慮將vw
單位運用於咱們的適配佈局中。
衆所周知,vw
是基於Viewport視窗的長度單位,這裏的視窗(Viewport)指的就是瀏覽器可視化的區域,而這個可視區域是window.innerWidth/window.innerHeight
的大小。用下圖簡單的來示意一下:
由於Viewport涉及到的知識點不少,要介紹清楚這方面的知識,都須要幾篇文章來進行闡述。@PPK大神有兩篇文章詳細介紹了這方面的知識。中文能夠移步這裏進行閱讀。
在CSS Values and Units Module Level 3中和Viewport相關的單位有四個,分別爲vw
、vh
、vmin
和vmax
。
vw
:是Viewport's width的簡寫,1vw
等於window.innerWidth
的1%
vh
:和vw
相似,是Viewport's height的簡寫,1vh
等於window.innerHeihgt
的1%
vmin
:vmin
的值是當前vw
和vh
中較小的值vmax
:vmax
的值是當前vw
和vh
中較大的值
vmin
和vmax
是根據Viewport中長度偏大的那個維度值計算出來的,若是window.innerHeight > window.innerWidth
則vmin
取百分之一的window.innerWidth
,vmax
取百分之一的window.innerHeight
計算。
仍是用一張圖來示意吧,一圖勝於千言萬語:
因此在這個方案中大膽的使用vw
來替代之前Flexible中的rem
縮放方案。先來回歸到咱們的實際業務中來。目前出視覺設計稿,咱們都是使用750px
寬度的,從上面的原理來看,那麼100vw = 750px
,即1vw = 7.5px
。那麼咱們能夠根據設計圖上的px
值直接轉換成對應的vw
值。看到這裏,不少同窗開始感到崩潰,又要計算,能不能簡便一點,能不能再簡單一點,實際上是能夠的,咱們可使用PostCSS的插件postcss-px-to-viewport,讓咱們能夠直接在代碼中寫px
,好比:
PostCSS編譯以後就是咱們所須要的帶vw
代碼:
在實際使用的時候,你能夠對該插件進行相關的參數配置:
假設你的設計稿不是750px
而是1125px
,那麼你就能夠修改vewportWidth
的值。有關於該插件的詳細介紹,能夠閱讀其官方使用文檔。
上面解決了px
到vw
的轉換計算。那麼在哪些地方可使用vw
來適配咱們的頁面。根據相關的測試:
vw
vw
1px
的邊框、圓角、陰影均可以使用vw
vw
另外有一個細節須要特別的提出,好比咱們有一個這樣的設計:
若是咱們直接使用:
最終的效果會形成[w-187-246]
容器的高度小於[w-188-246]
容器的高度。這個時候咱們就須要考慮到容器的長寬比縮放。這方面的方案不少,但我仍是推薦工具化來處理,這裏推薦@一絲 姐姐寫的一個PostCSS插件postcss-aspect-ratio-mini。這個插件使用很簡單,不須要作任何的配置,你只須要本地安裝一下就OK。使用的時候以下:
編譯出來:
這樣就能夠完美的實現長寬比的效果。有關於這方面的原理在這裏不作過多闡述,感興趣的話能夠閱讀早前整理的文章:
目前採用PostCSS插件只是一個過渡階段,在未來咱們能夠直接在CSS中使用
aspect-ratio
屬性來實現長寬比。
1px
方案前面提到過,對於1px
是不建議將其轉換成對應的vw
單位的,但在Retina下,咱們始終是須要面對如何解決1px
的問題。在《再談Retina下1px
的解決方案》文章中提供了多種解決1px
的方案。在這裏的話,我的推薦另一種解決1px
的方案。依舊是使用PostCSS插件,解決1px
可使用postcss-write-svg。
使用postcss-write-svg你能夠經過border-image
或者background-image
兩種方式來處理。好比:
這樣PostCSS會自動幫你把CSS編譯出來:
使用PostCSS的插件是否是比咱們修改圖片要來得簡單與方便。
上面演示的是使用border-image
方式,除此以外還可使用background-image
來實現。好比:
編譯出來就是:
這個方案簡單易用,是我所須要的。目前測試下來,基本能達到我所須要的需求。但有一點千萬別忘了,記得在<head>
中添加:
上面闡述的是這個適配方案中所用到的技術點,簡單的總結一下:
vw
來實現頁面的適配,而且經過PostCSS的插件postcss-px-to-viewport把px
轉換成vw
。這樣的好處是,咱們在擼碼的時候,不須要進行任何的計算,你只須要根據設計圖寫px
單位img
、vedio
和iframe
元素,經過PostCSS插件postcss-aspect-ratio-mini來實現,在實際使用中,只須要把對應的寬和高寫進去便可1px
的問題,使用PostCSS插件postcss-write-svg,自動生成border-image
或者background-image
的圖片這裏使用了多個PostCSS的插件,其實如今有不少優秀的PostCSS插件能幫助咱們解決不少問題。哪果你從未接觸過有關於PostCSS相關的知識,建議你能夠花點時間去學習一下,在W3cplus提供了一些有關於PostCSS相關的文章。若是你想系統的學習PostCSS相關的知識,推薦你購買《深刻PostCSS Web設計》一書:
最開始提到過,到目前爲止,T30的機型中還有幾款機型是不支持vw
的適配方案。那麼若是業務須要,應該怎麼處理呢?有兩種方式能夠進行降級處理:
vw
作處理,調用CSS Typed OM Level1 提供的CSSUnitValue
API。vw
單位的Polyfill主要有:vminpoly、Viewport Units Buggyfill、vunits.js和Modernizr。我的推薦採用Viewport Units Buggyfill採用vw
來作適配處理並非只有好處沒有任何缺點。有一些細節之處仍是存在必定的缺陷的。好比當容器使用vw
單位,margin
採用px
單位時,很容易形成總體寬度超過100vw
,從而影響佈局效果。對於相似這樣的現象,咱們能夠採用相關的技術進行規避。好比將margin
換成padding
,而且配合box-sizing
。只不過這不是最佳方案,隨着未來瀏覽器或者應用自身的Webview對calc()
函數的支持以後,碰到vw
和px
混合使用的時候,能夠結合calc()
函數一塊兒使用,這樣就能夠完美的解決。
另一點,px
轉換成vw
單位,多少還會存在必定的像素差,畢竟不少時候沒法徹底整除。
到目前爲止,我發現的兩個不足之處。或許在後面的使用當中,還會碰到一些其餘不爲人之的坑。事實也是如此,無論任何方案,踩得坑越多,該方案也愈來愈強大。但願喜歡這個適配方案的同窗和我一塊兒踩坑,讓其更爲完善。
雖然該文的示例,進行了多方面的測試。但不少同窗仍是會擔心本身的APP應用是否支持該方案,而不敢大膽嘗試或者使用。其實沒必要要這麼擔憂,你能夠拿本身的設備,或者應用掃描下面的二維碼:
當頁面跑完測試以後,找到對應的Values and Units列表項:
若是vw
欄是綠色表明你的設備或應用支持該方案;反之則不支持。另外你也能夠常常關注css3test相關的更新,後面將會根據相關的規範更新測試代碼,讓你能快速掌握哪些屬性能夠大膽使用。
H5頁面的適配方案老是使人蛋疼的,事實上頁面的佈局老是使人蛋疼的。但技術是不斷革新的,咱們能夠隨着保持對新技術的關注,嘗試這些新特性運用到實際項目中,只有這樣,咱們解決問題的方案纔會愈來愈完善。
到寫這篇文章爲止,雖然還有那麼一兩款機型不支持vw
,但並不影響咱們去使用。只有不斷去嘗試,纔會有進步。在此,但願你們大膽嘗試,一塊兒讓該方案變得更完美。若是你有更好的建議,或者你踩到任何坑,歡迎在下面的評論中與我分享,或者發郵件給我一塊兒討論。
著做權歸做者全部。
原文: https://www.w3cplus.com/css/vw-for-layout.html © w3cplus.com