1. 程式人生 > 實用技巧 >轉載:超詳細的rem+vw移動端螢幕適配方案

轉載:超詳細的rem+vw移動端螢幕適配方案

轉載自:https://blog.csdn.net/im_dogg/article/details/84369286

在說具體內容之前,我們必須瞭解幾個概念,就是:Retina屏、物理畫素、裝置獨立畫素、裝置畫素比

在CSS中我們一般使用px作為單位,需要注意的是,CSS樣式裡面的px和物理畫素並不是相等的。CSS中的畫素只是一個抽象的單位,在不同的裝置或不同的環境中,CSS中的1px所代表的物理畫素是不同的。在PC端,CSS的1px一般對應著電腦螢幕的1個物理畫素,但在移動端,CSS的1px等於幾個物理畫素是和螢幕畫素密度有關的。

1.Retina屏

所謂“Retina”是一種顯示標準,是把更多的畫素點壓縮至一塊螢幕裡

,從而達到更高的解析度並提高螢幕顯示的細膩程度。由摩托羅拉公司研發。最初該技術是用於Moto Aura上。這種解析度在正常觀看距離下足以使人肉眼無法分辨其中的單獨畫素。也被稱為視網膜顯示屏。

Retina屏一般在蘋果公司的產品上用的比較多,諸如MacBook、iPad、iPhone等

以MacBook Pro with Retina Display為例,工作時顯示卡渲染出2880x1800個畫素,其中每四個畫素一組,輸出原來螢幕的一個畫素顯示的大小區域內的影象。這樣一來,使用者所看到的圖示與文字的大小與原來的1440x900解析度顯示屏相同,但精細度是原來的4倍,但對於特殊元素,如視訊與影象,則以一個圖片畫素對應一個螢幕畫素的方式顯示。故不會產生

Windows中解析度提升使螢幕文字與影象變小,造成閱讀困難的問題。這樣在設計軟體時只需將所有的UI元素的精細度都提高到原來的4倍就可以既保持了觀看舒適度,又提高了顯示效果。關於iOS裝置,也由四個畫素代替原來一個畫素,通過下圖對比就可以較明顯地觀察到這種關係

2.物理畫素(physical pixel)

物理畫素又被稱為裝置畫素、裝置物理畫素,它是顯示器(電腦、手機螢幕)最小的物理顯示單位,每個物理畫素由顏色值和亮度值組成。所謂的一倍屏、二倍屏(Retina)、三倍屏,指的是裝置以多少物理畫素來顯示一個CSS畫素,也就是說,多倍屏以更多更精細的物理畫素點來顯示一個CSS畫素點,在普通螢幕下1個CSS畫素對應1個物理畫素,而在二倍

Retina螢幕下,1個CSS畫素對應的卻是4個物理畫素(參照上面Retina屏的原理下文田字示意圖理解)。

3.裝置獨立畫素(device-independent pixel)

裝置獨立畫素是我們寫CSS時所用的畫素,它是一個抽像的單位,主要使用在瀏覽器上,用來精確度量Web頁面上的內容。

4.裝置畫素比(device pixel ratio)

裝置畫素比簡稱為dpr物理畫素與裝置獨立畫素的比例

當這個比率為1:1時,使用1個裝置畫素顯示1個css畫素。當這個比率為2:1=2時,使用4(2*2)個裝置畫素顯示1個css畫素。當這個比率為3:1=3,使用9(3*3)個裝置畫素顯示1個css畫素。

這裡要注意,dpr=2,並不是物理畫素是裝置獨立畫素的2倍,而是用4個物理畫素去表示1個裝置邏輯畫素

應該說1個裝置獨立畫素是1個物理畫素的4倍!!!!!,因為你4個網物理畫素才代表我1個裝置獨立畫素

dpr只代表一個數字比例,不是倍數關係。

CSS的1px等於幾個物理畫素,除了和螢幕畫素密度dpr有關,還和使用者縮放有關係。例如,當用戶把頁面放大一倍,那麼CSS中1px所代表的物理畫素也會增加一倍;反之把頁面縮小一倍,CSS中1px所代表的物理畫素也會減少一倍。關於這點,在文章後面的1px細線問題部分還會講到。


viewport

viewport就是裝置上用來顯示網頁的那一塊區域,但viewport又不侷限於瀏覽器可視區域的大小,它可能比瀏覽器的可視區域要大,也可能比瀏覽器的可視區域要小。

在預設情況下,一般來講,移動裝置上的viewport都是要大於瀏覽器可視區域的,這是因為考慮到移動裝置的解析度相對於桌面電腦來說都比較小,所以為了能在移動裝置上正常顯示那些傳統的為桌面瀏覽器設計的網站,移動裝置上的瀏覽器都會把自己預設的viewport設為980px或1024px(也可能是其它值,這個是由裝置自己決定的),但帶來的後果就是瀏覽器會出現橫向滾動條,因為瀏覽器可視區域的寬度是比這個預設的viewport的寬度要小的。

這裡要認清三種視口

  •  visual viewport可見視口,指螢幕寬度
  •  layout viewport佈局視口,指DOM寬度
  •  ideal viewport理想適口,使佈局視口就是可見視口即為理想視口

獲取螢幕寬度(visual viewport)的尺寸:

window. innerWidth/Height

獲取DOM寬度(layout viewport)的尺寸:

document. documentElement. clientWidth/Height

設定理想視口ideal viewport:

<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

該meta標籤的作用是讓layoutviewport的寬度等於visual viewport的寬度,同時不允許使用者手動縮放,從而達到理想視口。 

  1.  meta[name="viewport"]裡各引數的含義為:
  2.   width: 設定layout viewport的寬度,為一個正整數,或字串”width-device”。
  3.   initial-scale: 設定頁面的初始縮放值,為一個數字,可以帶小數。
  4.   minimum-scale: 允許使用者的最小縮放值,為一個數字,可以帶小數。
  5.   maximum-scale: 允許使用者的最大縮放值,為一個數字,可以帶小數。
  6.   height: 設定layout viewport的高度,這個屬性對我們並不重要,很少使用。
  7.   user-scalable: 是否允許使用者進行縮放,值為“no”或“yes”。

1 rem適配

哇卡卡卡,終於說到移動端螢幕適配方案了,可能大家看的想罵娘了,不過別急啊,上面的東西弄不清楚,下面是適配也聽不懂啊

rem是相對於根元素的字型大小的單位,也就是html的font-size大小,瀏覽器預設的字型大小是16px,所以預設的1rem=16px,我們可以根據裝置寬度動態設定根元素的font-size,使得以rem為單位的元素在不同終端上以相對一致的視覺效果呈現。

事實上 rem是把螢幕等分成 指定的份數,以20份為例,每份為 1rem1rem 對應的大小就是 rem基準值rem做的就是把 rem基準值<html>font-size ,所以如果裝置的 物理畫素 寬為 640px,分成20份,那麼 1rem=640px/20=32px , <html>font-size為32px

  1. //這段程式碼放在head標籤裡面
  2. (function () {
  3. var html = document.documentElement;
  4. function onWindowResize() {
  5. html.style.fontSize = html.getBoundingClientRect().width / 20 + 'px';
  6. }
  7. window.addEventListener('resize', onWindowResize);
  8. onWindowResize();
  9. })();

當然,你也可以分成30份,40份,60份等等,這個看自己的喜好了

在我們實際切圖的時候,對於視覺稿上的元素尺寸換算,只需要元素的 原始的px值(即你量的大小) 除以 rem基準值 即可。例如設計稿的大小為640px, rem基準值 = 640px/20 = 32px ,有個元素的大小你量出來是 140px286px* ,那麼換算過來就是:

  1. 140px = 140/32 = 4.375rem
  2. 286px = 286/32 = 8.9375rem

這樣我們就可以用rem來代替畫素px了,而且在所有的移動端都是自適應的

這個方法目前是比較好的適配方法,只是rem在計算時很麻煩,有很多小數,這個時候大家可以試一下用less.js解決rem的小數問題


2 rem+vw適配

什麼是vw和vh?

  • vw : 1vw 等於視口寬度的1%
  • vh : 1vh 等於視口高度的1%
  • vmin : 選取 vw 和 vh 中最小的那個
  • vmax : 選取 vw 和 vh 中最大的那個

用視口單位度量,視口寬度為100vw,高度為100vh(左側為豎屏情況,右側為橫屏情況)

例如,在桌面端瀏覽器視口尺寸為650px,那麼 1vw = 650 * 1% = 6.5px(這是理論推算的出,如果瀏覽器不支援0.5px,那麼實際渲染結果可能是7px)

注意:這裡的1%是指佔視口的1%,而不是我們定義的div的1%

如何利用rem+vw進行螢幕適配呢?我們以設計稿為750px為基準

第一步:設定meta標籤

<meta name="viewport" content="width=device-width, initial-scale=2.0, maximum-scale=2.0, minimum-scale=2.0, user-scalable=no">

因為iPhone6以及大多數的dpr為2,為了第二步的方便進行換算

第二步:設定html的font-size大小

html{font-size:13.33333333vw}

為什麼font-size=13.33333333vw?

下面分析下原理吧, 上面我們說了vw表示1%的螢幕寬度,而我們的設計稿通常是750px的,螢幕一共是100vw,對應750px,那麼1px就是0.1333333vw,。

同時我們知道rem,rem是相對html元素的字型大小,為了方便計算,我們取html的font-size=100px,通過上面的計算結果1px是0.13333333vw,那麼100px就是13.333333vw了

所以,我們讓1rem=100px=13.333333vw

那麼在專案上就很好地可以進行使用了

當我們通過ps測量一個div的大小為 width:200px,height:137px時,我們就可以這樣寫,ps量出來的畫素直接除以100,計算小數很方便

  1. div {
  2. width: 2rem;
  3. height:1.37rem;
  4. }

是不是相對於前面的rem適配來說,不用去計算小數了呢?

但是注意,這是針對於dpr=2的適配,至於其他dpr適配,要根據設計師的設計稿規定

1)如果你的設計圖是640px或者750px,那麼dpr的取值就是2,meta如下設定

<meta name="viewport" content="width=device-width, initial-scale=2.0, maximum-scale=2.0, minimum-scale=2.0, user-scalable=no">

3)如果你的設計圖是1080px,那麼css畫素就是1080px,那麼dpr的取值就是3,這個時候,meta要如下設定

<meta name="viewport" content="width=device-width, initial-scale=3.0, maximum-scale=3.0, minimum-scale=3.0, user-scalable=no">

然後rem的計算方法和dpr=2時一樣。

rem+vw適配解決了小數問題,但是相容性不太好,所以看大家怎麼選擇了