1. 程式人生 > >一次搞清楚移動端這幾個坑爹的單位慨念

一次搞清楚移動端這幾個坑爹的單位慨念

目錄:

  • 一、讓坑爹的單位,不再坑爹
  • 二、需要準備什麼樣的設計稿
  • 三、rem方案的原理和細節

    • 高清屏上,點陣圖的處理
    • 高清屏上,關於border: 1px的處理
    • 移動端螢幕的自動適配的處理
    • 移動端螢幕上字型大小的處理

一、讓坑爹的單位,不再坑爹

移動端適配本身不難,但是因為涉及到單位轉換,想要解釋清楚移動端適配方案,你必須要搞清楚各個單位的慨念。

但是由於中英翻譯的問題,我發現很多文章在講解移動端適配時,關於單位,我們有一萬種翻譯方法...

"物理畫素、邏輯畫素、物理解析度、邏輯解析度、實際畫素、css畫素、裝置畫素、ppi、pt、dpr。"

真的是給我們新手學習移動端適配造成不少困惑,英語真的很重要呀。下面分享一下,我覺得最靠譜最需要理解的4個慨念。

推薦把這4個名詞記住,我覺得翻譯的很貼切,好理解。

  • 物理畫素(physical pixel) : 顯示器上最小的物理顯示單位,蘋果的retina螢幕很清晰吧?就是因為它的物理畫素很高。
  • 裝置獨立畫素(density-independent pixel) : 這個是計算機座標系統裡的虛擬慨念,這個點代表一個可以由程式使用的虛擬畫素(比如: css畫素)
  • 裝置畫素比(device pixel ratio) : 也叫dpr。 裝置畫素比 = 物理畫素 / 裝置獨立畫素 。你也可以通過window.devicePixelRatio獲取裝置畫素比
  • 點陣圖畫素 : png, jpg, gif這類都是點陣圖,點陣圖畫素就是點陣圖的最小資料單元

舉個栗子

以iphone6來說,

  • 物理畫素解析度: 750 * 1334
  • 裝置獨立畫素解析度 : 375 * 667
  • 裝置畫素比: 2

不管是高清螢幕還是普通螢幕,一個11 css畫素那麼大的物理尺寸是一樣的,區別在於高清屏上一個一個11 css畫素那麼大的地方,對應2*2個物理畫素,所以很清晰。

在普通螢幕下1個css畫素(11)對應1個物理畫素(11)

在高清螢幕下1個css畫素(11)對應4個物理畫素(22)

不知道看完這個例子,你是否能理解這些叫法的區別。如果還是有些迷糊,可以看下面的補充說明 ; 如果已經瞭解,可以跳過下面一小節。

關於這4個叫法的補充說明:

  • 物理畫素(physical pixel): 物理畫素越大,螢幕越清晰。
  • 裝置獨立畫素(density-independent pixel) : 也叫密度無關畫素。這個裝置獨立畫素,就是你眼睛看到的手機大小有關。

2個手機看上去一樣大? 那他們裝置獨立獨立畫素就是一樣的。也就是說我不管你高清屏還是什麼**屏裝置獨立畫素只跟我這個裝置看上去大不大有關。

裝置看上去很大? 那裝置獨立畫素就大 ; 裝置看上去很小? 那裝置獨立畫素就小

所以我覺得裝置獨立畫素(density-independent pixel)。這個翻譯比較貼切也好理解。只跟裝置看上去的大小相關。

很多翻譯也管裝置獨立畫素叫做: 邏輯畫素 、 css畫素 、 實際畫素...

二、需要準備什麼樣的設計稿

  • 首先,選取一款手機的螢幕寬高作為基準(以前是iphone4的320×480,現在更多的是iphone6的375×667)。
  • 對於retina螢幕(如: dpr=2),為了達到高清效果,視覺稿的畫布大小會是基準的2倍,也就是說畫素點個數是原來的4倍(對iphone6而言:原先的375×667,就會變成750×1334)。

三、rem方案的原理和細節

rem方案的原理:

讓需要動態變化的佈局、圖片的單位都用rem來寫。比如width: 2rem

那麼2rem究竟表示多少呢? 這個和根元素html的font-size屬性相關, 比如font-size為75px,那麼 2rem 就表示150px

所以只要html的font-size可以根據螢幕的尺寸和dpr動態的變化,那麼所有以rem為單位的元素都會動態變化。

這個就是rem能夠適配的基本原理。至於螢幕的尺寸和dpr都是可以通過js或者css獲取的。

細節1: 高清屏上,點陣圖的處理

常見的點陣圖,包括png / jpg / gif型別的圖片。只有一個位影象素對應一個物理畫素時,點陣圖才會被高質量的顯示

所以常見的問題就是: png圖片在普通螢幕上正常顯示,但是在高清屏上,會出現點陣圖畫素不夠的情況,導致圖片模糊。

所以其實比較好的解決方案就是:

  • 在根據不同的dpr,顯示不同的點陣圖。
  • 另一個就是可以不用點陣圖,改用向量圖、字型圖示、轉成base64。不用點陣圖自然就沒有點陣圖的問題了。

細節2: 高清屏上,border: 1px的處理

其實並不是所有做移動端適配的人,都一定會遇到這個問題。

比如你的設計師給了一張iphone6為基準的 750*1334 的設計稿,裡面有一個border標註的是1px。

所以設計師實際上想要的是retina屏下的1px,也就是普通螢幕下的0.5px。

但問題是: 並不是手機端螢幕都支援0.5px,ios7之下或者安卓機都可能把0.5解析成0px

這裡給到一種解決方案: 設定initial-scale=0.5

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

這樣,頁面中的所有的border: 1px都將縮小0.5,從而達到border: 0.5px;的效果。

然而,頁面scale,必然會帶來一些問題:

  • 字型大小會被縮放
  • 頁面佈局會被縮放(如: div的寬高等)

細節3: 移動端螢幕的自動適配的處理

rem原理: 根據手機的螢幕尺寸和dpr,動態的修改html的font-size(基準值)

求rem

    1 rem = document.documentElement.clientWidth * dpr / 10
    
   (1) 乘以dpr,是因為頁面有可能為了實現1px border頁面會縮放(scale) 1/dpr 倍(如果沒有,dpr=1),。
   (2) 除以10,是為了取整,方便計算(理論上可以是任何值)

求iphone6的1rem 例子:

iphone6的 1rem : 375px * 2 / 10 = 75px

知道1rem是多少後,如何寫其他的css呢?

比如width: 150px, 我們就可以寫成2rem

實際上,我們往往通過一個px2rem的函式,來做轉換。演算法就是 設計稿上某個div的寬度值 / 1rem的畫素值, 例如 : 150px / 75px = 2rem

細節4: 移動端螢幕上字型大小的處理

移動端上,關於字型大小的需求,一般都是希望各個螢幕的字型都是保持一樣大的。

一般解決方案,就是根據dpr,設定不同的font-size,讓字型大小保持一致

文章來源:北大青鳥學校開發實驗小組