當前位置:
首頁 > 知識 > 茴字的四種寫法——淺談移動前端適配

茴字的四種寫法——淺談移動前端適配

原文:https://segmentfault.com/a/1190000014309664

話說我剛工作的時候,就開始用rem了,過了沒多久,接觸到了flexible,系統化且支持iOS的retina屏迅速征服了我,最近又看到了大漠大神的vw。所以本文想完成一篇一站式的文章,可以系統的了解前端適配的演進。閑話少敘,馬上開始。

1. 什麼是前端適配

從UI展現層面上:我們期望不同尺寸的設備,頁面可以自適應的展示或者進行等比縮放,從而在不同的尺寸的設備下看起來協調或者差不多

從代碼實現層面上:我們希望前端適配可以用用儘可能簡潔的代碼來實現。最好一套代碼實現兼容所有設備,而不是對每個或每種設備都寫一套方案,不是次次都選用最無奈的方案(Android和iOS分開編寫)。

2. 關鍵字

如果你了解這些關鍵字,那麼這段大可以跳過,如果後面遇到了問題,感覺有些疑惑,也可以再回來查閱。


2.1 Viewport/視口

通俗的講,移動設備上的viewport就是設備的屏幕上能用來顯示我們的網頁的那一塊區域[1],但不一定是我們可見的區域。具體來說,分為以下三種。

2.1.1 Visual Viewport

Visual Viewport: 可見視口。就是移動設備上可以被我們看見的部分。寬度在移動端通過window.innerWidth獲得(僅限移動端,PC上哪怕是chrome模擬也會有不同的結果)。

2.2.2 Layout Viewport

Layout Viewport: 布局視口。

如果把PC上的頁面放到移動端,以iphone8為例,如果只展示為可見視口的寬度(375px),那麼頁面會被壓縮的特別窄而顯示錯亂,所以移動瀏覽器就決定默認情況下把viewport設為一個較寬的值,比如980px,這樣的話即使是那些為桌面設計的網站也能在移動瀏覽器上正常顯示了。[1]

而事實上,我們一般看不到如上圖這樣出現橫向滾動條的界面;在手機上訪問頁面時,往往是下圖的樣子:

這是由於頁面body寬度設置了100%而沒有指定一個具體的寬度導致的,從而使頁面被等比縮放了。由於用戶可以縮放,所以還算能正常瀏覽。

2.2.3 Ideal Viewport

Ideal Viewport:理想視口,其實就是設備的可見區域,和可見視口一致。

設置Ideal Viewport的好處是,只要按照Ideal Viewport來設計樣式稿,用戶就不用能最完美的查看網站的內容——既不用左右滑動,也不用放大縮小。

設置理想視口:

這段代碼的意思是將布局視口的寬度設置為設備寬度,初始縮放比例為1,最大縮放比例為1,用戶不能縮放。


2.2 像素

2.2.1 物理像素

物理像素:一個物理像素是顯示器(手機屏幕)上最小的物理顯示單元,在操作系統的調度下,每一個設備像素都有自己的顏色值和亮度值。[2]

2.2.2 設備獨立像素

設備獨立像素:又稱為CSS像素,就是我們日常代碼中使用的像素。瀏覽器內的一切長度都是以CSS像素為單位的,CSS像素的單位是px。

2.2.3 設備像素比

設備像素比(簡稱dpr)定義了物理像素和設備獨立像素的對應關係。比如說對於iOS的retina屏,一個設備獨立像素就對應著4個物理像素。這樣的設計可以使畫面更加清晰銳利,如下圖:

3. 業界的解決方案

OK,LongLongAgo的前綴之後,終於到了正題。回到我們最開始的初心:我們只是想要通過一套代碼,實現一個可以在不同頁面尺寸上展示差不多的頁面。在這一塊,現在主要有三種方案。


3.1 Rem的解決方案

DPR一致時,px在不同的屏幕尺寸上會展示為定寬,這就導致我們的頁面可能會出現滾動條或者占不滿的情況。而通過rem來設置div的寬高,可以保證頁面可以通過調整html的font-size來整體放大或者縮小,從而達到不管屏幕寬度是多少,頁面都能完美展示的效果。

例如,針對750*1334的設計稿:

這樣,所有的設備的寬度都是7.5rem,只需要把設計稿上的px值統一除以100,就可以得到相應的rem值了。

網易也採用的這種方法。


3.2 Flexible.js

Flexible是阿里團隊開發的前端適配方案,也是用的rem的方法。那麼第一種方法其實已經能解決前端適配問題了,為什麼阿里還要開發一個Flexible呢?

在第一種方法中,dpr=1時沒有任何問題,但是在dpr=2或者更高的手機屏幕上,因為物理像素的增加,存在小於1px的顯示空間。如果採用第一種方法,因為它統一對scale設置為1,那麼我們假如想要實現0.5px, 就只能通過transform的方式。如果有多個這樣的樣式,代碼就會變得很麻煩。

因此,阿里的flexible方案充分考慮了這種情況,動態的設置了fontsize和scale, 從而使得CSS中的1px等於物理像素中的1px,在IOS下得到最清晰的體驗。

具體的大家可以看《使用Flexible實現手淘H5頁面的終端適配》

另外需要指出的一點是:Flexible將頁面分成了100份,頁面的寬度是10rem,對於750的設計稿,我們需要用相應的px數除以75來得到。手動計算是愚蠢的,不同的編譯器都可以下載pix2rem插件(可以直接寫px然後自動轉換為相應的rem值),直接使用sass或者postcss打包也能達到同樣的功能。

總結一下上面兩種rem方法,主要思想為:

根據dpr的值來修改html的font-size,從而使用rem實現等比縮放

根據dpr的值來修改viewport實現1px的線

但是Flexible也有它的局限性,具體表現為:

不能與響應式布局兼容

對Android沒有做處理,導致1px和backgroudImage還要額外做處理的問題[4]

所以我們有了第三種解決方案——vw。


3.3 vw

vw是基於Viewport視窗的長度單位,在CSS3中和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中較大的值

其實vw的方案的寫法和flexible方案的寫法一致——因為flexible其實就是用hack的手段模擬了vw的實現而已。

具體寫法:針對750px的設計稿,將相應的px值除以7.5就是vw的值。

因為此方法不會改變可見視口的寬度,所以可以和media query通用了,另外,也支持了Android上高解析度屏的展示。

儘管在某些Android機型上還存在兼容問題,我們也可以使用Viewport Units Buggyfill,具體見《如何在Vue項目中使用vw實現移動端適配》

總結

正如大漠所說,flexible模擬vw的時代已經過去,真正的酋長vw已經歸來

參考文檔:

《移動前端開發之viewport的深入理解》

《移動端高清、多屏適配方案》

《再聊移動端頁面的適配》

《基於淘寶彈性布局方案lib-flexible的問題研究》

《如何在Vue項目中使用vw實現移動端適配》

END

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 JavaScript 的精彩文章:

關於Google發布的JS代碼規範,你需要了解什麼?
跟隨 Chrome,Firefox 將阻止載入大多數 FTP 資源

TAG:JavaScript |