10分鐘從原理分析移動端H5適配方案,讓你適配不再慌亂(一)

FE_xuer發表於2017-12-11

前言:前端的你,是否曾竊喜終於甩掉了IE6,卻一個轉身,猝不及防踏入移動端碎片大坑,今天過後,可以不用太過於糾結了,因為可以我幫你重塑對移動端的認識,從此以後,得心應手,提升效率不是夢。 知己知彼,百戰不殆,我們前端開發也一樣。知其然,知其所以然,不論從裝逼或者實際開發的角度來說,都是百益而無一害的。我們來看一小段程式碼:

<html style="font-size:75px;" >
<head>
<meta name="viewport" content="initial-scale=0.5,maximun-scale=0.5,user-scalable=no" />
</head>
<body>
</body>
</html>
複製程式碼

相信這個程式碼大家都已經很熟悉了,主要做了兩個事,1、定義rem;2、定義viewport縮放比例。當然了,如果僅僅以為我又是炒這兩盤人盡皆知的冷飯,那就太小看我咯。我們需要更加深入瞭解瀏覽器(當然包括webview啦),從而更加從容進行適配開發。 首先第一個問題,前端佈局開發,到底是幹嘛的呢?從本質上來講,主要就是操作畫素從而實現各種頁面效果,那我們就從畫素開始講起咯。

一、首先,我們要知道幾個基本概念。

1、css畫素

我們使用css操作到的畫素叫做css畫素,也就是裝置無關畫素,顧名思義也就是與裝置無關。

2、物理畫素

既然有無關,那就肯定存在與裝置有關的咯,也就是我們的物理畫素了。我們操作css畫素,然後由物理畫素進行表達,在Retina屏出來以前,css畫素的數量===物理畫素,也就是說1css畫素的影象就是通過1物理畫素進行表達,在pc大屏上,這個效果是足夠的,但是在手機瀏覽器中,是不夠的,因此蘋果率先推出Retina屏。

3、裝置獨立畫素比

devicePixelRatio=物理畫素/css畫素,以下簡稱dpr,在Retina屏出來以前,dpr===1,Retina出現後,dpr>=1.5的螢幕如雨後春筍般出現。

4、螢幕解析度

螢幕上顯示的畫素個數,在微軟的pc時代很多人有個誤解,螢幕解析度跟螢幕大小成正比的,總覺得提升解析度就要提升螢幕尺寸,其實不然,4k解析度的屏都已應用到諾大一個手機屏了。

5、畫素密度(ppi)

每英寸螢幕的畫素數,這個屬性跟螢幕解析度是有直接關係的,一般來說,高畫素密度的屏,螢幕解析度也越大。

6、viewport

這是移動開發中及其重要的概念,早期移動端的viewport與pc的viewport是一個概念,導致小屏體驗不佳,後來蘋果引入可視視窗(visualviewport)和佈局視窗(layoutviewport)。簡單解釋一下,這兩個視窗是透視的效果,想象下layoutviewport是一張大的不能改變大小和角度的圖片。我們透過visualviewport對layoutviewport進行觀察(可以看看George Cummins在Stack Overflow上的解釋)。觀察距離遠點(使用者的縮小頁面功能)就可以一次性看到這個大圖。或者近點(使用者的放大頁面功能)可以看到一部分。你能改變這個透視框的方向,但這張大圖片的大小和形狀都不會改變。我們在<meta name="viewport" /> 設定的其實是layout-viewport,使得layoutviewport==visualviewport,達到idealviewport效果,使得viewport剛好完美覆蓋螢幕,因此適配方案的時候,這一句最重要。

二、適配方案

我們在做佈局方案的時候肯定是希望使用某種通用的佈局方案,面對如此多的dpr,最好的方式就是根據dpr的不同比例進行適配,儘量避免使用媒體佈局針對每一套裝置進行適配,那真就成了搬磚碼農。這裡我會根據淘寶前端提供的flexible佈局方案進行分析,回到我們開頭的第一段程式碼,我們需要設定meta viewport和和rem,我們暫不考慮特殊情況,rem=window.innerWidth/10

1、第一種方案:根據dpr進行螢幕的縮放,達到dpr=1的效果

這種方案怎麼理解呢,例如你的iphone6,Retina屏dpr=2,那麼你的viewport meta設定應該如下:<meta name="viewport" content="initial-scale=0.5,user-scalable=no"/> 那麼,這一句如何理解呢,因為dpr=2,說明一個css畫素由2*2個物理畫素進行表達,我們設定initial-scale=0.5也就是將我們的css畫素大小縮小兩倍,同一個螢幕上可用的css畫素也就是變成了原來的兩倍。比如裝置尺寸375,dpr=2,這時候,我們可操作的畫素值實際是375x2=750,我們進行換算的時候,rem=window.innerWidth/10=750/10=75,我們將這個75稱為基準rem,這時候,我們的需要根據750的設計稿進行佈局計算,也就是我們常說的二倍圖。當不同的裝置進行適配,只要根據實際計算的rem值與基數rem進行換算就達到了我們適配的目的。

2、第二種方案:無論dpr值為何,initial-scale=1

這種方案從本質上來講,跟第一種方案是一致的,不過它保持了dpr帶給我的原始特性,沒有將css畫素點進行縮放,這時候,同樣以上述裝置尺寸375,dpr=2進行舉例,我們實際可操作的畫素值依舊是375,這種情況下我們的基準rem就是window.innerWidth/10=375/10=37.5。

結論:以上兩種雖然基準rem不同,但是方案在本質上是一致的

這如何理解呢?我們來舉兩個例子理解一下,1、因為都是相對於基準rem佈局,假設我們需要全屏顯示,width都是10rem。2、同樣基於兩倍圖進行佈局,比如我們有一張100*100大小的圖片,我們需要顯示100 *100大小,dpr=2的裝置上顯示,無論哪一種方案,必然模糊,首先來看第一種方案,畫素點縮小一半導致模糊,第二種方案,每一個畫素點都由4個畫素進行渲染,只能取近似值,因此也會導致模糊,結果是都會模糊,但是兩種方案都有其異同,因此我們想要在二倍屏顯示100 *100的圖片,圖片也必須是二倍圖,200 * 200。

結語

在瞭解了基本原理之後,相信你可以實現自己的一套佈局方案了,當然了,如果嫌麻煩,不想重複造輪子,淘寶團隊的flexible方案就夠用了,原理是一致的嘛。

參考文件:

相關文章