web移動端適配

適配達到的效果是什麼?不一樣尺寸的手機設備上,頁面「相對性的達到合理的展現(自適應)」或者「保持統一效果的等比縮放(看起來差很少)」。javascript

基本概念

在瞭解適配方案前,讓咱們來了解一些基本的概念。css

以iphone6爲例html

  • 分辨率:750pt×1334pt
  • 屏幕尺寸:4.7in
  • 屏幕像素密度:326ppi

物理像素(physical pixel)

物理像素又被稱爲設備像素,他是顯示設備中一個最微小的物理部件。每一個像素能夠根據操做系統設置本身的顏色和亮度。所謂的一倍屏、二倍屏(Retina)、三倍屏,指的是設備以多少物理像素來顯示一個CSS像素,也就是說,多倍屏以更多更精細的物理像素點來顯示一個CSS像素點,在普通屏幕下1個CSS像素對應1個物理像素,而在Retina屏幕下,1個CSS像素對應的倒是4個物理像素。html5

iphone6屏幕上垂直有1334個物理像素,水平有750個物理像素。java

css像素(device-independent pixel)

設備獨立像素,不一樣於設備像素(物理像素),它是虛擬化的。好比說css像素,咱們常說的10px其實指的就是它。android

設備像素比dpr(device pixel ratio)

設備像素比簡稱爲dpr,其定義了物理像素和設備獨立像素的對應關係segmentfault

設備像素比 = 物理像素 / 設備獨立像素瀏覽器

屏幕像素密度PPI(pixel per inch)

屏幕像素密度是指一個設備表面上存在的像素數量,它一般以每英寸有多少像素來計算(PPI)。屏幕像素密度與屏幕尺寸和屏幕分辨率有關,在單一變化條件下,屏幕尺寸越小、分辨率越高,像素密度越大,反之越小。bash

屏幕密度 = 對角線分辨率/屏幕尺寸app

視口

佈局視口(layout viewport)

簡單來講就是DOM寬度

PC瀏覽器中,有一個用來約束CSS佈局視口的東西,又叫作初始包含塊。這也就是全部寬高繼承的由來。除去margin、padding,佈局視口和瀏覽器可視窗口寬度是一致的,同時也和瀏覽器自己的寬度一致。 可是在移動端不同 繼續以iphone6爲例,這裏沒加meta標籤

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <style> * { margin: 0; padding: 0; } html, body { height: 100%; width: 100%; } .left { float: left; width: 20%; height: 100%; background: red; } .right { float: right; width: 80%; height: 100%; background: green; } </style>
</head>

<body>
  <div class="left"></div>
  <div class="right"></div>
</body>

</html>
複製代碼

咱們會看到body的寬度是980px,而瀏覽器的寬度只有375px。這裏的980px就是移動端所謂的佈局視口了

視覺視口(visual viewport)

簡而言之就是屏幕寬度

理想視口(ideal viewport)

佈局視口很明顯對用戶十分的不友好,徹底忽略了手機原本的尺寸。 因此蘋果引入了理想視口的概念,它是對設備來講最理想的佈局視口尺寸。理想視口中的網頁用戶最理想的寬度,用戶進入頁面的時候不須要縮放。 那麼很明顯,所謂的理想寬度就是瀏覽器(屏幕)的寬度了,使佈局視口就是視覺視口

對pc端來講:

狀態 佈局視口 視覺視口
默認 相等 相等
放大 變小 變小
縮小 變大 變大

對移動端來講:

狀態 佈局視口 視覺視口
默認 偏大 相等
放大 不變 變小
縮小 變大 變大

meta標籤作了什麼

<meta name="viewport" content="width=device-width,initial-scale=1">
複製代碼

width=device-width 這句代碼能夠把佈局視口設置成爲瀏覽器(屏幕)的寬度

initial-scale=1 的意思是初始縮放的比例是1,使用它的時候,同時也會將佈局視口的尺寸設置爲縮放後的尺寸。而縮放的尺寸就是基於屏幕的寬度來的,也就起到了和width=device-width一樣的效果

相關實現方式

動態設置視口縮放

主要三點:

  • 設置理想視口
  • 動態設置視口縮放爲1/dpr
  • px單位的適配

設置理想視口

設置理想視口,使得DOM寬度(layout viewport)屏幕寬度(視覺視口)(visual viewport)同樣大,DOM文檔主寬度即爲屏幕寬度。1個CSS像素(1px)由多少設備像素顯示由具體設備而不一樣。

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

動態設置視口縮放爲1/dpr

對於安卓,全部設備縮放設爲1,對於IOS,根據dpr不一樣,設置其縮放爲dpr倒數。設置頁面縮放可使得1個CSS像素(1px)由1個設備像素來顯示,從而提升顯示精度;所以,設置1/dpr的縮放視口,能夠畫出1px的邊框。

無論頁面中有沒有設置viewport,若無,則設置,如有,則改寫,設置其scale爲1/dpr。

(function (doc, win) {
  var docEl = win.document.documentElement;
  var resizeEvt = 'orientationchange' in window ? 'orientationchange' : 'resize';
  var metaEl = doc.querySelector('meta[name="viewport"]');
  var dpr = 0;
  var scale = 0;

  // 對iOS設備進行dpr的判斷,對於Android系列,始終認爲其dpr爲1
  if (!dpr && !scale) {
    var isAndroid = win.navigator.appVersion.match(/android/gi);
    var isIPhone = win.navigator.appVersion.match(/[iphone|ipad]/gi);
    var devicePixelRatio = win.devicePixelRatio;

    if(isIPhone) {
      dpr = devicePixelRatio;
    } else {
      drp = 1;
    }
    
    scale = 1 / dpr;
  }

  /** * ================================================ * 設置data-dpr和viewport × ================================================ */

  docEl.setAttribute('data-dpr', dpr);
  // 動態改寫meta:viewport標籤
  if (!metaEl) {
    metaEl = doc.createElement('meta');
    metaEl.setAttribute('name', 'viewport');
    metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
    document.documentElement.firstElementChild.appendChild(metaEl);
  } else {
    metaEl.setAttribute('content', 'width=device-width, initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no');
  }

})(document, window);
複製代碼

px單位適配

相似於這樣,在動態設置scale的時候,能夠給元素加上[data-dpr="2"]這樣的屬性進行字體適配(可是沒法適配1.75這樣的...)

.p {
    font-size: 14px;

  [data-dpr="2"] & {
    font-size: 14px * 2;
  }

  [data-dpr="3"] & {
    font-size: 14px * 3;
  }
}
複製代碼

rem

定義:font size of the root element

而rem是相對於根元素,這樣就意味着,咱們只須要在根元素肯定一個參考值,使得以rem爲單位的元素在不一樣終端上以相對一致的視覺效果呈現。

flex佈局

更多內容請參考阮一峯老師的:

vm/vh

視窗(Viewport)是你的瀏覽器實際顯示內容的區域——換句話說是你的不包括工具欄和按鈕的網頁瀏覽器。這些單位是vw,vh,vmin和vmax。它們都表明了瀏覽器(視窗(Viewport))尺寸的比例和窗口大小調整產生的規模改變。

  • vw——表明視窗(Viewport)的寬度爲1%。
  • vh——窗口高度的百分比。
  • vmin——vmin的值是當前vw和vh中較小的值。
  • vmax——大尺寸的百分比。

你能夠在任何一個可使用像素值的地方使用它們,好比width,height,margin,font-size等等。它們將經過窗口大小的調整或旋轉設備的瀏覽器來從新計算這些值。

響應式佈局

響應式針對的是不一樣分辨率設備而進行的適配式設計,以利用@media規則爲主要手段,而自適應則忽略@media以比例佈局爲主,目的是適應不一樣的瀏覽器窗口大小。

響應式的問題在於:

  • 屏幕分辨率分區間:區間內沒法進行區分,沒法實現100%兼容,通常是用主流分辨率來進行劃分;
  • 額外的工做量:響應式佈局的工做都是須要開發者去實現的,帶來了額外的開放量; 不適合功能複雜的頁面:響應式通常適合用於資訊類頁面,功能複雜的網站對於頁面的總體排版和樣式要求較高(特別是對比PC和H5)
  • 影響性能(試想一下淘寶這種大型網站,一個分頁下的商品條目特別多,而且每一個商品條目的dom結構又十分複雜,並且pc端每每顯示的信息是要比手機端更多的。若是不分開作兩套,而是直接用響應式的話,那麼pc端上顯示的不少dom就要在手機端上隱藏,結果這些dom都沒有被用到,可是卻加載了。在這個流量和速度至上的時代,代碼冗餘先不說,多加載的這些無用的代碼而消耗的流量,從某種意義上來講就已經損失了不少的效益)

移動端適配方案

固定高度,寬度自適應

屬於自適應佈局,viewport width 設置爲 device-width,以較小寬度(如 320px)的視覺稿做爲參照進行佈局。垂直方向的高度和間距使用定值,水平方向混合使用定值和百分比或者利用彈性佈局

關鍵點:

  • 以小寬度做爲參照是由於若是佈局知足了小寬度的擺放,當屏幕變寬時,簡單的填充空白就能夠了;而若是反過來就可能形成「擠壞了」。
  • 須要小寬度的佈局,又須要大寬度的圖像,這是一個矛盾點。 320px 過於窄小,不利於頁面的設計;只能設計橫向拉伸的元素佈局,存在不少侷限性。

固定寬度,viewport 縮放

視覺稿、頁面寬度、viewport width 使用統一寬度,利用瀏覽器自身縮放完成適配。頁面樣式(包括圖像元素)徹底按照視覺稿的尺寸,使用定值單位 (px、em)便可完成。

利用 rem 佈局

依照某特定寬度設定 rem 值(即 html 的 font-size),頁面任何須要彈性適配的元素,尺寸均換算爲 rem 進行佈局;當頁面渲染時,根據頁面有效寬度進行計算,調整 rem 的大小,動態縮放以達到適配的效果。利用該方案,還能夠根據 devicePixelRatio 設定 initial-scale 來放大 viewport,使頁面按照物理像素渲染,提高清晰度。

具體參考:使用Flexible實現手淘H5頁面的終端適配

參考資料

相關文章
相關標籤/搜索