移動端適配 - 基礎知識篇

這是一個系列文章,分 3 篇:
javascript

單位

CSS中的單位

相對單位

font-size相關 說明
rem 相對於根元素(html元素)的font-size
em 相對於元素的font-size的計算值
ex 相對於元素字體的小寫x的高度
ch 相對於元素字體中的字形「0」的寬度

viewport相關 說明
vw 相對於視口寬度 1vw = window.innerWidth * 1%
vh 相對於視口高度 1vw = window.innerHeight * 1%
vmin vw和vh中較小的值
vmax vw和vh中較大的值

window.innerHeight 瀏覽器窗口的視口(視覺視口)高度(單位:像素,大小是css像素的數量),包括水平滾動條。css

window.innerWidth 瀏覽器視口(視覺視口)寬度(單位:像素,大小是css像素的數量),包括垂直滾動條。html

絕對單位

  • px
    • 與設備屏幕相關
    • 對於普通屏幕,一般是顯示器的一個設備像素(點)
    • 對於打印機或高分辨率的屏幕,一個CSS像素對應多個設備像素

安卓中的單位

  • dp
    • 在定義UI佈局時使用的虛擬像素單位,用於以密度無關方式表示佈局維度或位置
    • 1dp = 160 dpi 屏幕上的1個物理像素
    • 在定義應用的 UI 時應始終使用 dp 單位 ,以確保在不一樣密度的屏幕上正常顯示 UI
  • sp
  • px

ios中的單位

  • pt
  • px

參考

像素(pixel)

設備像素(physical pixel)

設備像素又稱物理像素(physical pixel),是顯示器中最小的物理單元,設備能控制顯示的最小單位。 每一個像素根據操做系統的指示設置本身的顏色和亮度。java

任何設備的物理像素數量都是固定的android

設備獨立像素DIP

由程序使用並控制的虛擬像素,好比web編程中的CSS像素(px)、安卓(dp)、ios系統(pt)中的設備獨立像素.ios

CSS像素

CSS像素是Web編程中的概念,瀏覽器使用的抽象單元。 一般,CSS像素被稱爲與設備無關的像素(DIP)。在標準密度顯示器上,1個CSS像素對應於1個設備像素。css3

例如:web

<div height="200" width="300"></div>
複製代碼

在普通屏幕上繪製200x300設備像素,在retina顯示屏上爲保證相同的物理尺寸,相同的div將使用400x600設備像素,這樣在Retina顯示屏上,相同物理表面的設備像素數量是普通顯示屏的四倍。算法

image.png

設備像素與設備獨立像素

設備像素與設備獨立像素有必定的對應關係,咱們編程時控制的是設備獨立像素,而後由相關係統轉換爲物理像素。編程

一個CSS像素至關於多少個設備像素由屏幕特性(是不是高密度)和縮放比例決定。放大得越大,一個CSS像素覆蓋的設備像素越多。

分辨率

顯示器能顯示的物理像素的數量,顯示器可顯示的像素越多,畫面就越精細。

屏幕像素密度(Screen density)

屏幕像素密度是指物理表面的像素數量,一般以每英寸像素測量(PPI,pixel per inch)。ppi的值越高,畫質越好。

蘋果公司爲其雙重密度顯示器創造了「Retina」營銷術語,聲稱人眼再也不可以將屏幕上的各個像素與「天然」觀看距離區分開來。

image.png

要計算顯示器的屏幕像素密度(每英寸像素值),首先要肯定屏幕尺寸和分辨率。

image.png

例如,蘋果的iphone6s,像素分辨率: 1334 x 750,對角線長度4.7英寸。

image.png

那屏幕像素密度就是:

image.png

蘋果公司認爲,人類能肉眼識別的最高像素密度是300ppi

image.png

如今也有愈來愈多高分辨率的安卓手機(顯示屏)與蘋果iPhone的視網膜顯示器相同。
根據屏幕每英寸像素值的不一樣,Android系統的開發者將平板電腦和手機的屏幕分紅五類:

名稱 顯示等級 每英寸像素值 類似ppi的ios設備分類
LDPI @0.75x 低等像素密度 大約120ppi
MDPI @1x 中等像素密度 大約160ppi 標準點@1x
HDPI @1.5x 高等像素密度 大約180ppi
XHDPI @2x 極高像素密度 大約320ppi 視網膜 @2x
XXHDPI @3x 超高像素密度 大約480ppi 高清視網膜 @3x

設備像素比dpr

  • 縮放比爲1時的物理像素分辨率與CSS像素分辨率的比值
  • 在js中能夠經過 window.devicePixelRatio獲取,也能夠重寫window.devicePixelRatio來更改dpr
  • css中可使用媒體查詢  device-pixel-ratio

位圖像素(Bitmap Pixel)

位圖像素是基於柵格的圖像(JPG、PNG、GIF)中最小的單位,每一個像素都包含屏幕上的顯示信息,如位置、顏色等,有的圖像信息還包含不透明度(Alpha Channel)。

image.png

位圖圖像除了自有的光柵分辨率,在web網頁中有一個用CSS像素定義的抽象尺寸,web瀏覽器根據CSS設置的高度和寬度屬性在屏幕上繪製基於柵格的圖像,根據CSS尺寸可能會擠壓或拉伸圖像。

當在標準密度顯示器上以完整尺寸繪製光柵圖像時,1個位圖像素對應1個設備像素,圖像徹底保真顯示。由於位圖像素不能進一步分割,在retina顯示屏中,位圖像素應該是標準屏上的4倍才能保真高清顯示。

image.png

一般爲Retina屏提供圖像的方法是經過使用HTML或CSS編程手段將圖像容器尺寸減半。

例如,要展現 200 x 300像素的圖像(這是css像素),能夠向服務器請求位圖分辨率爲400 x 600像素(4倍)的圖像。

<img src="https://img.meituan.net/beautyimg/0e03672ea40f4f692f193349b86aeb90299167.jpg%40400w_600h_1e_1c_1l_100q%7Cwatermark%3D0"/>
複製代碼
img{
	width:200px;
	height: 300px;
}
複製代碼

在標準密度顯示器上,有一個下采樣的過程。對於位圖像素400x600的圖像,要在200 x 300的設備像素上展現,須要對其進行2倍下采樣,獲得(400/2)x(600/2)的分辨率圖像。那其實就是把 2 x 2窗口內的位圖像素變成一個像素,這個像素點的值就是窗口內全部像素的均值。

image.png

圖像下采樣原理

對於一幅圖像I尺寸爲M_N,對其進行s倍下采樣,即獲得(M/s)_(N/s)尺寸的得分辨率圖像,固然s應該是M和N的公約數才行,若是考慮的是矩陣形式的圖像,就是把原始圖像s*s窗口內的圖像變成一個像素。 這個像素點的值就是窗口內全部像素的均值: pk = ∑i∈win(k)Ii / s2

圖像上採樣原理

圖像放大幾乎都是採用內插值方法,即在原有圖像像素的基礎上在像素點之間採用合適的插值算法插入新的元素。

爲了在Retina顯示屏上可以高清保真顯示圖像,須要加載2倍圖像。但對於標準顯示屏設備,若是一樣使用2倍圖像,會有幾個問題:

  • 須要下載更大的圖片資源,形成資源浪費
  • 根據所使用的下采樣算法,2倍圖像在標準密度屏幕上會丟失一些銳度

這就是如何在移動端不一樣分辨率設備中圖片高清保真顯示的問題,不一樣屏幕密度的設備應該加載不一樣大小的圖像,保證在不一樣設備上都能保真顯示。

移動端圖片高清顯示問題

CSS媒體查詢與background-image配合使用

能夠經過媒體查詢的方式,對不一樣dpr設備使用不一樣分辨率的圖像。

.icon {
  background-image: url(example.png);
  background-size: 200px 300px;
  height: 300px;
  width: 200px;
}

@media only screen and (-Webkit-min-device-pixel-ratio: 1.5),
only screen and (-moz-min-device-pixel-ratio: 1.5),
only screen and (-o-min-device-pixel-ratio: 3/2),
only screen and (min-device-pixel-ratio: 1.5) {
  .icon {
    background-image: url(example@2x.png);
  }
}
複製代碼

dpr查詢使用1.5而不是2,能夠用相同的語句來查詢其餘非Apple設備。
這種方式主要用於使用background-image屬性顯示的圖像。

優勢

  • 設備僅下載合適的目標資源
  • 跨瀏覽器兼容
  • 像素精確控制

缺點

  • 編程代碼繁瑣,特別是在大型網站上
  • 對於內容展現型圖像顯示爲其餘HTML元素的背景,這在語義上是不正確的

js控制加載合適尺寸的圖像

可使用window.devicePixelRatio在Javascript中查詢dpr,比CSS更容易設置圖像。 然而,因爲使用JavaScript,渲染可能會延遲。

$(document).ready(function(){
  if (window.devicePixelRatio > 1) {
    var images = $('img');

    images.each(function(i) {
      var lowres = $(this).attr('src');
      var highres = lowres.replace(".", "@2x.");
      $(this).attr('src', highres);
    });
  }
});
複製代碼

這種方式比較適合展現內容型圖像。

優勢

  • 易於實現
  • 非Retina設備不須要下載大的圖片資源
  • 像素精確控制

缺點

  • Retina設備必須下載1倍圖和2倍圖
  • 圖像替換效果在Retina設備上能體現
  • window.devicePixelRatio不支持IE或Firefox。

其餘方案
  • 可縮放矢量圖形SVG
    無論使用什麼方法,光柵圖像都會被位圖分辨率限制,不是無限可擴展的。但矢量圖形無限縮放都不會影響清晰度
<img src="sample.svg" width="300" height="200" />
複製代碼
  • 字體圖標 Icon Fonts

參考

視口

在桌面瀏覽器中只有一個視口,視口的寬度 = 瀏覽器窗口寬度。在小屏的移動設備(寬度240px~640px)中,若是視口寬度和瀏覽器寬度同樣,那爲桌面瀏覽器設計的網頁在移動端查看時會很醜,因此移動端瀏覽器廠商會設置一個默認的移動設備的視口寬度,在768px ~ 1024px之間,最多見的寬度是980px。

佈局視口

CSS的佈局將根據上面介紹的視口來計算,因此在移動端這就叫佈局視口

image.png

視覺視口

雖然移動端默認的佈局視口寬度可讓爲桌面瀏覽器設計的網頁很好的展現,但只會有一部份內容展現在可視區域,這個區域被稱爲視覺視口。用戶能夠經過縮放來操做視覺視口。

image.png

理想視口

對於移動端網頁,默認的佈局視口的寬度並非一個理想的寬度,咱們不但願須要經過縮放查看內容,因此瀏覽器廠商引進了理想視口的概念,與理想視口寬度相同的網頁是最理想的用戶瀏覽的寬度,剛進入頁面時用戶不須要縮放。

那對於移動端網頁,咱們須要設置佈局視口的寬度爲理想視口的寬度。這須要在meta標籤中聲明:

<meta name="viewport" content="width=device-width"/>
複製代碼

參考

meta標籤

上面提到了經過meta標籤聲明佈局視口的寬度。
meta標籤的經常使用屬性:

屬性 可選值 描述
charset UTF-8等 聲明當前文檔所使用的字符編碼
name author、description 、keywords、 viewport等 把 content 屬性關聯到一個名稱
http-equiv content-type 、expire 、refresh 、set-cookie 把content屬性關聯到HTTP頭部
content name屬性相關的元信息,格式:key=value 定義與http-equiv或name屬性相關的元信息

對於viewport元標籤格式:

<meta name="viewport" content="key=value, key=value"/>
複製代碼

其中content內容:

  • width:佈局視口寬度(數值 / device-width)(範圍從200 到10,000,默認爲980 像素)
  • height:佈局視口高度(數值 / device-height)(範圍從223 到10,000)
  • initial-scale:初始的縮放比例 (範圍從>0 到10)
  • minimum-scale:容許用戶縮放到的最小比例
  • maximum-scale:容許用戶縮放到的最大比例
  • user-scalable:用戶是否能夠手動縮 (no,yes)

對於移動端頁面,常將佈局視口寬度設置爲理想視口寬度,並禁止縮放:

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

參考

媒體查詢

媒體查詢類型

  • 媒介類型查詢
  • 視口相關
  • 特性相關

語法

@media 媒體類型 and (視口特性閥值){
    // 知足條件的css樣式代碼
}
複製代碼

媒體查詢示例

.sample {
    background-image: url(sample.png);
    width: 300px;
    height: 200px;
}
 
@media only screen and (-Webkit-min-device-pixel-ratio: 1.5),
  only screen and (-moz-min-device-pixel-ratio: 1.5),
  only screen and (-o-min-device-pixel-ratio: 3/2),
  only screen and (min-device-pixel-ratio: 1.5) {
    .sample {
        background-image: url(sample@2x.png);
    }
}
複製代碼

更多用法參考

相關文章
相關標籤/搜索