移動端適配方案是一個老生常談的話題,可是對於不一樣的項目、不一樣的業務場景可能會須要不一樣的適配方案來進行移動端適配,向下兼容的baseline也須要提早訂好。css
其實移動端適配就和下面的玩具同樣,對應的形狀塞到對應的容器裏面就行了。可是有點小小的問題,就是這些積木的大小可能和容器不太同樣,對於前端來講,這些積木不是用木頭作的,而應該是用橡皮泥作的。html
業務環境是決定總體項目的適配方案的核心因素。一套代碼到底須要兼容多少環境是在項目開始架構的時候就須要肯定的。前端
程序員交友網站,github主站能夠明顯的看到,全部的內容都被限制到了一個980像素的內容區域裏面。git
而其移動端也也很明顯的是一個單獨的佈局方式,總體寬度再也不限制,即便到了iPad Pro這種寬度到達1024像素的設備上,仍然會佔滿整個屏幕。程序員
而淘寶的主站和github相似,分爲移動端頁面和PC端頁面,PC端頁面一樣有着左右的留白,這也是爲了讓用戶可以在寬屏的時候將注意力集中在中間區域。github
當前大部分站點都採用UA來判斷用戶的設備,而後定向到PC或者H5頁面。web
二者的惟一不一樣點在於:淘寶會更加嚴格地將頁面直接重定向到另一個連接,而github則是加載了一個不一樣的CSS文件進行渲染。固然,這兩種方案其實沒有本質的差異,而單獨的H5頁面能夠在客戶端站內進行更好地複用。瀏覽器
因此,若是有足夠的開發人員,開發適用於兩種設備類型的頁面是比較友好的方案。若是你的移動客戶端是基於webview開發的話,那麼H5頁面還能夠直接嵌入到webview中做爲展現。sass
對於總體寬度,正常移動設備的寬高比都比較協調,而像iPad這種設備,其寬度過大,致使了正常的H5頁面在上面顯示會有比較奇怪的效果。好比淘寶的主站在iPad上的顯示效果,能夠看到上下兩塊的navigator被拉長了不少,致使了效果很差。可是若是考慮到成本問題,iPad用戶更多地會使用APP來進行訪問,因此H5頁面的樣式重要性就被縮減了。而github移動版對於寬屏設備的適配就會作得更好。架構
有興趣的話,能夠去看看淘寶的H5頁面,這個頁面有一個頗有趣的地方,這個地方後文會講到,這裏先提一下:
除了寬度仍舊佔滿屏幕寬度的方案,設置屏幕的最大寬度能夠保證在寬屏設備上的顯示效果,可是留白的部分就須要考慮處理方案。
因爲有了固定最大寬度,僅僅須要對於超過寬度的具備留白的設備進行特殊處理(能夠是背景、功能按鈕等),中間具備最大寬度的部分就能夠進行代碼複用。
考拉團隊的這篇blog寫的已經很是清楚了,感謝考拉的小夥伴給咱們提供了便宜的海淘還有這麼好的文檔產出lol:
桌面瀏覽器中,正常的視口寬度就是整個瀏覽器的窗口寬度,會隨着瀏覽器窗口的伸縮而縮放。默認狀況下HTML標籤會佔滿整個視口,若是沒有設置HTML的靜態width的話。
若是採用以前所述的,PC端頁面設置最大寬度的話,那麼當視口在最大寬度以外的時候縮放的話,不會影響可見區域的顯示效果,可是若是縮小到比最大寬度小的時候,原頁面的佈局方案就很重要了。彈性佈局和百分比的佈局方式可以在頁面縮小的時候,保證頁面的佈局不會崩潰。
在手機上,視口與移動端瀏覽器的寬度再也不關聯,而是徹底獨立的了。咱們稱其爲佈局視口。
整個頁面可能會變得很大,而後只有一部分顯示在設備的可見區域內,整個頁面的大小叫作Layout Viewport。這個大小能夠經過document.documentElement.clientHeight/clientWidth
來獲取。
PPK這篇很早的文章對於視口進行了很是清晰的描述。
上圖可見,Layout Viewport的寬高實際上是可變的,當經過手勢縮放頁面的時候,Layout Viewport就會發生變化,當頁面縮放到和設備的可見區域大小一致的時候,Layout Viewport就恰好等於Visual Viewport了。
Visual Viewport其實很好理解,就是整個屏幕的可見區域大小。因爲設備的物理像素,也就是CSS中的pt
單位是固定的,頁面在移動端被縮放了以後,頁面中的CSS像素分佈在設備上也發生了變化。
Ideal Viewport實際上是上面二者的結合,當咱們將Layout Viewport的寬度設置成屏幕的寬度,就保證了頁面中CSS像素點的恆定。
這裏就用到了移動端適配經常使用的<meta name="viewport" content="width=device-width">
這個標籤能夠保證在移動端設備中,頁面的寬度與屏幕寬度相同。
在手機上進行放大的時候,頁面中的CSS像素不變,可是可見視口的像素比例發生了變化,可是禁用縮放會致使某些用戶的體驗較差。保持縮放比例在必定範圍以內比較合適。
基於如上所述的內容,結合目前的業務內容--主要針對移動端設備進行適配,採用設置最大寬度,而且在meta
標籤中設置理想視口,能夠保證在移動設備以及PC上面的總體佈局效果。
目前對於移動端適配的內容佈局效果是這樣的:
以上幾個方法各自都有各自的好處,咱們能夠看一下實際應用時候的效果:
使用百分比做爲內容大小的標準,在大部分條件下是可行的,百分比能夠很好地讓元素乖乖呆在本身的位置,不管屏幕的寬度大小。
可是文字就存在很是大的問題了,因爲文字是固定大小,在屏幕dpr變化的時候,文字的CSS像素不變,就致使了文字在頁面中的佔位發生了變化。這樣的結果就是,文字過多或者屏幕dpr太小的時候,會發生溢出;可是若是按照小屏幕爲基準,又會發生字體過小這種狀況。
百分比在當前移動端適配排版的時候,更多地會做爲section
級別元素的兼容排版。這個也要和設計稿中的效果相關,若是設計稿中要求一個元素定寬,那麼就直接用px
來保證寬度就能夠了。
rem
這個單位和以前經常使用的em
有點相似,惟一的區別在於rem
及基於根元素的font-size
來進行計算的一個相對值。em
存在不少缺點,好比層層嵌套以後,可能就會忘記了上一層的font-size
究竟是多大。或者好比像如今的模塊化開發,一個路由套在另外一個路由裏面,甚至找父元素都須要到其餘文件中去找。
爲了解決em
存在的問題,標準中還有rem
這個單位來幫助排版。全部的元素大小都用rem
來做爲單位,而後在頁面的根元素中,咱們爲根元素的font-size
進行肯定化地賦值,這樣全部的rem
單位都是同一個明確的基準了。當屏幕進行適配的時候,只須要調整這個基準值,就能夠保證每一個元素的大小自動按照比例調整。
阿里的lib-flexible解決方案實際上就是利用了這個方式,經過給<html>
標籤綁定font-size
以及data-dpr
屬性來進行整個頁面的適配。
方案將整個頁面寬度分紅100份,分紅100份的緣由能夠看下面的另外一個方案。每10個單位寬度做爲1rem
,也就是整個視覺稿的寬度會被分紅10rem
的100份,假如拿到的視覺稿是750px
的,那麼1rem
就表明75px
。這樣獲得的比例係數就是75/750
,也就是每次在進行設計稿到CSS的轉換的時候,只須要對設計稿的像素值/10就能夠獲得對應的rem
值。
經過一個預先加載的JavaScript腳本,計算根節點的字體大小,document.documentElement.style.fontSize = window.innerWidth / 10 + 'px';
,而後咱們在寫頁面代碼的時候只須要將原始的像素值/基準值就能夠獲得對應的rem
單位了。固然每次都要按計算器確定是不行的。若是想方便使用的話,能夠用less或者sass這種預處理器來處理頁面。
@function px2rem($px) // 這裏將設計稿的px轉換爲rem, @return ($px / $unit-px) * 1rem // 根據設備的dpr進行字體適配 @mixin font-dpr($font-size) font-size: $font-size [data-dpr="2"] & font-size: $font-size * 2
除了元素寬高能夠獲得比較好的還原,對於文字大小的適配也比較重要,因爲每一個設備的dpr不一樣(這裏尤爲是iOS設備),直接致使了不少文字在iPhone6+上顯示正常,而在iPhone5上面卻文字過大,致使文字溢出,上面的less mixin
就是進行字體樣式適配的。
這種方法結合了sass
的函數功能和rem
的適配,再加上必要的百分比以及media query能夠獲得比較好的移動表現。
這是使用這種方法在iphone6上的顯示效果,具體的總體顯示效果能夠戳這裏,rem基準樣式示例
若是對於文字在各類平臺上的顯示效果不滿意,能夠經過上面說的sass
的mixin
來讓文字根據dpr
進行斷點渲染。
而這樣存在的問題就是僅僅適用於移動端,而且不可以進行橫屏適配,由於橫屏以後,頁面的寬度發生了變化,可是基準值卻還保持着本來綁定到根節點上面的基準值。
首先看看vw
的瀏覽器支持狀況吧,can i use vw支持狀況,使用這個單位意味着你放棄了IE11如下的PC用戶,在如今一個主要兼容移動端的世界裏,並無太大的反作用(這裏吐槽一句,其實PC端的兼容遠遠要比移動端來的方便。移動端奇奇怪怪的分辨率以及2x,3x的屏幕,還有苦逼的ipad、橫屏讓我每次作兼容的時候想一躍解千愁)。
vw
自身將整個可見視口橫向分紅了100份,每個單位就是1vw
,這個單位最大的優點就是在移動端的時候,不管是豎屏或者橫屏,vw
永遠都是針對於橫向的,比rem
的方案好在當屏幕大小發生變化(順便兼容了之後的可調節屏幕大小的移動設備[手動斜眼])的時候,不會讓頁面崩掉。
對於移動設備來講,好比iphone6+的375px
CSS像素寬度,1vw
就等於3.75px
,經過這個單位能夠解決上面的依賴於腳本綁定根元素font-size
的問題,在豎屏和橫屏下面都有比較好的效果。
在經過vw
解耦了CSS和JS以後,那麼vw
是否能夠獨立解決全部問題呢?
// 首先,我司的設計稿目前都是以750px爲寬度,實際爲iPhone6+的375px爲基準 $w-base: 375px $w-base-design: 750px @function px2vw($px) @return ($px / $w-base-design) * 100vw
首先,上面的sass
代碼能夠根據你設計稿上面的px
單位轉換爲vw
單位值。固然最簡單的辦法仍是直接按照視覺稿上面像素進行輸入,而後直接輸出對應的vw
值啦。vscode和sublime固然會有已經作好的插件,可是我的並非很喜歡這種方式,這樣你就沒辦法獲得這個視覺稿本來的像素值了。在後期進行維護的時候會增長不少不少不少麻煩。這就是寫起來爽,改起來火葬場吧。。。vw的效果能夠看下面的codepen。
目前來講,vw
是確定不適合單獨使用的,畢竟頁面中仍是有不少元素須要絕對的大小定位的。px
永遠是必不可少的,視覺不可能讓你全部的東西都自適應。
那麼vw
可以解決什麼問題呢?首先是大部分取代%
在CSS中的使用,百分比在CSS中存在不少歧義,對於寬度,上下邊距,左右邊距,內外邊距的處理方式不盡相同。即便是老練的前端有時候也得思考一下當前的百分比究竟是根據什麼肯定的。而vw
則是一個絕對的數值,僅僅根據一個不太可能變化的屏幕寬度來肯定。
而百分比主要解決的彈性問題,就是vw
着力解決的問題。
vw
不可以兼顧全部的狀況,因此這個單位目前還並非最終的解決方案,仍是須要和其餘單位合做來幫助頁面可以更加優雅地顯示出來。
雖然根據實現出來的效果,幾種方法可能沒有什麼太大的效果差異,可是最大的問題在於,須要實現這種效果須要多麼複雜的代碼呢。
CSS的兼容性不在於解釋器上,而是在於設備的屏幕上面。大部分時間不只須要將頁面展現在用戶的面前,而是須要將頁面穩定且優雅地展現給用戶。
不管是百分比,rem
仍是vw
,都是進行局部容器元素定位的,做爲最底層的葉子元素或者單元元素來講,更多時間仍是會使用px
來儘可能還原視覺稿。
長遠考慮這個問題,vw
在僅進行移動端訪問的狀況下效果拔羣,由於不考慮兼容,只須要考慮適配問題。工程中到底使用哪一個方法進行,取決於大部分業務須要兼容的環境。