移動端原理和適配方案

移動端開發不可避免的一個點就是適配問題,因爲機型繁多,屏幕尺寸大不相同,以及retina屏幕致使一套固定的樣式佈局沒法知足全部的屏幕需求,所以須要解決各類屏幕的適配問題,讓頁面在全部手機上看起來都合適美觀。
到目前爲止,在適配問題上經歷了幾個階段:css

  1. 百分比佈局,拋棄px儘可能用%,對於一些較小的元素和邊框來講並不友好,我的認爲%比較適合作頁面結構劃分,不太適合較小元素的大小設置
  2. 媒體查詢(@media),根據屏幕寬度執行不一樣樣式,可是隻能按設備寬度區間作大致區分,不夠細緻,代碼繁重
  3. 百分比+媒體查詢,經過百分比作layout佈局,具體元素用媒體查詢單獨設置,缺點同上
  4. rem佈局,經過rem單位,動態設置html標籤的fontSize,目前比較成熟的適配方案,經常使用的有淘寶適配方案flexible,螞蟻金服的ant design mobile
  5. flex佈局,移動端兼容較好

後面會針對rem適配具體說明html

基本概念

物理像素
又叫設備像素,一個物理像素是屏幕上的最小顯示單元,每一個像素都有本身的顯示顏色和亮度,例如,屏幕上顯示的一張100px*100px的圖片,其實是由不少個擁有顏色和亮度的像素點組成。前端

設備獨立像素
又叫作密度無關像素、邏輯像素,是由程序能夠控制的虛擬像素,咱們樣式中的css像素也是邏輯像素的一種。系統會將邏輯像素轉化爲設備像素展現。html5

設備像素比
物理像素與設備像素之間的關係就是設備像素比,dpr = 物理像素/設備獨立像素。
能夠經過 window.devicePixelRatio 獲取設備像素比。react

即便知道了基本概念,可能也仍是不清楚他們之間到底有什麼關係?有怎樣的表現?如下經過簡單的例子來進行理解。webpack

圖片描述

上圖是屏幕尺寸相同,dpr分別爲1和2的展現效果,最直觀的視覺效果就是左側dpr=1的顯示比較模糊粗糙,右側dpr=2的更加清晰細緻,產生區別的緣由不是由於右側的圖案比左側的大,而是在尺寸相同的狀況下右側屏幕爲retina屏幕,dpr=2,這意味着,當展現一個100px*100px大小的圖案時,dpr=1的屏幕上在100px*100px的區域內顯示了100*100個物理像素點,用一個物理像素顯示1個邏輯(css)像素,可是在dpr=2的屏幕上卻展現了100*100*4個像素點,用4個物理像素展現1個邏輯(css)像素,因此圖案更加清晰細膩。以下圖所示:git

圖片描述

也能夠簡單的理解爲,在尺寸相同,密度不一樣的屏幕上展現同等大小的內容,那麼密度大的就要用更多的像素去展現。這裏的密度指單位面積內的像素點個數,像素點越多,分辨率越大,越清晰。github

主流適配方案

目前流行的移動端適配方案分別爲螞蟻金服的ant-design-mobile中的高清適配方案和淘寶的flexible,可是兩種方案的原理是同樣的,viewport+rem,這裏主要記錄兩種方案的使用方式,原理在下面分析。web

ant-design

阿里螞蟻金服的react組件庫,在antd mobile中提供移動端高清適配方案,簡單介紹下使用使用方式,在建立項目並安裝antd-mobile後npm

1.安裝依賴

npm install --save-dev babel-plugin-import less less-loader

2.修改webpack配置
修改配置支持按需引入,加載antd-mobile的less文件

圖片描述

增長配置,解析編譯less,引入主題配置,這裏的theme是package.json中的配置項

圖片描述

package.json中增長theme設置項,theme能夠定製組件皮膚顏色,高清方案hd需爲2px,具體參數參看antd-mobile官網,這裏也有使用方式

圖片描述

3.px轉rem
antd裏px轉rem方便快捷的方式是經過依賴postcss-plugin-px2rem,配置後在開發中能夠直接寫px單位,編譯後生成px單位。
安裝依賴:

npm install postcss-plugin-px2rem postcss-loader --save-dev

對.css文件作解析編譯配置,增長postcss-loader配置,postcss-loader的options裏增長postcss-plugin-px2rem相關配置,以下圖,具體使用根據本身工程配置方式作變通:

圖片描述

rootValue默認設置100,即1rem = 100px;

flexible

1.引入flexible.js文件
flexible.js能夠下載到本地工程引入,也能夠引cdn上的遠程文件,該文件執行會自動生成<meta name='viewport'> 標籤,不須要手動寫

2.開發使用
因爲會自動生成meta標籤,並自動設置html標籤的font-size屬性,因此只須要按照設計稿寫rem單位的css便可。默認iphone6 1rem = 75px,其計算方式是1rem=document.documentElement.clientWidth*dpr/100 = 375*2/100=75px

無輪以上那種方式,在開發模式上能夠用同一種,以iphone6爲標準,UI出750*1334(高度不固定)的設計稿,前端開發元素大小同設計圖。

px轉rem方式

px轉rem有幾種比較好用的方式

一、不用sass,less,直接在寫css的過程當中自行計算rem,麻煩耗時而且開工做量大,若是之後改變rem對px的開發標準,那麼所有須要從新計算。
二、 使用sass開發,且不用構建工具,那麼可使用sass的混合宏、函數計算rem;也能夠IDE安裝轉換插件。sass函數以下:

// px rem轉換函數
@function px2rem($px, $base-font-size: 75px) {
  @if (unitless($px)) {
    @warn "Assuming #{$px} to be in pixels, attempting to convert it into pixels for you";
    @return px2rem($px + 0px);
  } @else if (unit($px) == rem) {
    @return $px;
  }
  @return ($px / $base-font-size) * 1rem;
}

三、 使用構建工具,能夠npm安裝px2rem插件
antd推薦:https://github.com/ant-tool/p...
flexible推薦:https://github.com/songsiqi/p...

適配原理解析

移動端適配的根本在於rem+viewport

css單位由px轉向rem

這裏暫時不考慮retina屏幕問題,下面解析

這裏說一下px、em、rem單位的區別:
1px = 1px
1em = 父元素的font-size
1rem = html標籤的font-size

因爲rem單位的特性,使得以rem做爲單位的元素在大小等屬性上具備相對性,以元素的width,height爲例,根元素的font-size越大,那麼元素的寬高越大,反之越小。這就意味着當咱們以iphone6爲基礎作rem佈局:
iphone6

html: font-size = 100px

div:  width = 1rem = 100px 
      height = 1rem = 100px

在 iphone6 plus 上的顯示會以下,因爲plus屏幕較大,html的fontSize屬性等比例變大,元素尺寸一樣會相應變大,這樣就能夠達到根據屏幕尺寸不一樣,頁面元素作等比例縮放,達到基本的適配目的。

html標籤的fontSize的值可在頁面加載的時候經過js進行計算,動態設置設置,計算方式爲:
fontSize = 當前屏幕寬度/基礎設備寬度*基礎設備上約定的html標籤fontSize

iphone6 plus

screenWidth: 414px
html: font-size =  414/375*100px = 110.4px

div:  width = 1rem = 110.4px
      height = 1rem = 110.4px

以上根據屏幕尺寸計算html的fontSize值的方式可以實現的是頁面在iphone6(開發基礎稿)的基礎上根據屏幕寬度進行簡單的等比例縮放,可是卻沒法解決retina屏幕的問題,若是開發中以iphone6爲基礎,那麼考慮到其dpr=2的問題,應該用寬度爲750px的設計稿做爲開發稿。

根據dpr作頁面縮放
上面主要解釋rem的適配原理,如今來解釋dpr的問題。

若是忽略了dpr的不一樣,會有什麼樣的問題呢?

最主要的問題就是展現一樣的大小的內容,在dpr越大的屏幕上頁面元素內容會越虛,尤爲是圖片和1px border的問題。
緣由是上面提到的dpr越大,一個邏輯像素對應的物理像素就越多,圖片也會越清除細膩,反之越粗糙模糊。之因此會虛是由於展現100px*100px的圖片,dpr=1的屏幕一個物理像素展現一個邏輯像素;dpr=2的屏幕四個物理像素展現1個邏輯像素,四個物理像素如何展現一個邏輯像素呢,系統在計算的時候,會把一個邏輯像素補充爲4個色值,透明度等近似的邏輯像素點,這樣圖片展現就會顯得虛。

移動開發retian屏幕常見問題

疑問思考

1.antd iphone6 1rem = 100px 6p 1rem=150rem 設置width:7.5rem,6上寬度100%,6p上沒法顯示寬度100%,

相關文章
相關標籤/搜索