移動裝置的使用者越來越多,每天android手機的激活量都已經超過130萬台,是以我們面向移動終端的WebAPP也開始跟進了。本文主要介紹webapp的開發與調試的相關知識和經驗,以及給出幾種可選的解決方案。
一、基本概念
(1) CSS pixels與device pixels
CSS pixels:浏覽器使用的抽象機關, 主要用來在網頁上繪制内容。
device pixels: 顯示螢幕的的最小實體機關,每個dp包含自己的顔色、亮度。
等值的 CSS pixels在手機螢幕上占多大的位置,這不是固定的,這取決于很多屬性。
(2) PPI/DPI
PPI,有時也叫DPI,所表示的是每英寸所擁有的像素(pixel)數目,數值越高,即代表顯示屏能夠以越高的密度顯示圖像。(注:這裡的像素,指的是device pixels。)搞清楚了PPI是什麼意思,我們就能很容易了解PPI的計算方式了,我們需要首先算出手機螢幕的對角線等效像素,然後處以對角線(我們平常所說的手機螢幕尺寸就是說的手機螢幕對角線的長度),就可以得到PPI了。準确的計算公示大家可以參照下圖。比較有意思的是,根據公式計算出來的iPhone 4的PPI為330,要比蘋果官方公布的326要高一點點。

同理,以HTC G7為例,480*800的分辨率,3.7英寸,算出來就是252的PPI。
(3) 密度決定比例
我們計算PPI就是為了知道一部手機裝置是屬于哪個密度區間的,因為不同的密度區間,對應着不同的預設縮放比例,這是一個很重要的概念。
由上圖可知,PPI在120-160之間的手機被歸為低密度手機,160-240被歸為中密度,240-320被歸為高密度,320以上被歸為超高密度(Apple給了它一個上流的名字——retina)。
這些密度對應着一個特定的縮放比例值,拿我們最熟悉的iphone4或4s來說,它們的PPI是326,屬于超高密度的手機。當我們書寫一個寬度為320px的頁面放到iphone中顯示,你會發現,它竟然是滿寬的。這是因為,頁面被預設放大了兩倍,也就是640px,而iphone4或4s的寬,正是640px。
圖中把高密度的一類圈起來,是因為這是android手機的統計資料,在國内安卓手機市場中,高密度的裝置占了絕大多數的市場佔有率,這是很重要的一點,也是我們做安卓端webapp要注意的關鍵點。
(4) viewport的使用
viewport總共有5個屬性,分别如下:
<meta name="viewport"
content="
height = [ pixel_value |device-height] ,
width = [ pixel_value |device-width ] ,
initial-scale = float_value , minimum-scale = float_value , maximum-scale = float_value ,
user-scalable =[yes | no] ,
target- densitydpi = [ dpi_value | device-dpi| high-dpi | medium-dpi | low-dpi] " />
在這些屬性裡面,我們重點關注`target-densitydpi`,這個屬性可以改變裝置的預設縮放。`medium-dpi`是`target-densitydpi`的預設值,如果我們顯式定義`target-densitydpi=device-dpi`,那麼裝置就會按照真實的dpi來渲染頁面。打個比方說,一張`320*480`的圖檔,放在iphone4裡面,預設是占滿螢幕的,但如果定義了`target-densitydpi=device-dpi`,那麼圖檔隻占螢幕的四分之一(二分之一的平方),因為iphone4的分辨率是`640*960`。
二、解決方案
(1) 簡單粗暴
如果我們按照320px寬的設計稿去制作頁面,并且不做任何的設定,頁面會預設自動縮放到跟手機螢幕相等的寬度(這是由于 medium-dpi是target-densitydpi的預設值,和不同密度對應不同縮放比例所決定的,這一切都是移動裝置自動完成的 )。是以這種解決方案,簡單,粗暴,有效。但有一個緻命的缺點,對于高密度和超高密度的手機裝置,頁面(特别是圖檔)會失真,而且密度越多,失真越厲害。
(2) 極緻完美
在這種方案中,我們采用 `target-densitydpi=device-dpi`,這樣一來,手機裝置就會按照真實的像素數目來渲染,用專業的話來說,就是1 CSS pixels = 1 device pixels。比如對于 `640*960`的 iphone,我們就可以做出 `640*960`的頁面,在iphone上顯示也不會有滾動條。當然,對于其他裝置,也需制作不同尺寸的頁面,是以這種方案往往是使用媒體查詢來做成響應式的頁面。這種方案可以在特定的分辨率下完美呈現,但是随着要相容的不同分辨率越多,成本就越高,因為需要為每一種分辨率書寫單獨的代碼。下面舉個簡單的例子:
<meta name="viewport"content="target- densitydpi =device-dpi, width=device-width " />
#header {
background:url (medium-density-image.png);
}
@media screen and (- webkit -device-pixel-ratio:1.5) {
/* CSS for high-density screens */
#header { background:url (high-density-image.png);}
@media screen and (- webkit -device-pixel-ratio:0.75) {
/* CSS for low-density screens */
#header { background:url (low-density-image.png);}
(3) 合理折中
針對安卓裝置絕大多數是高密度,部分是中密度的特點,我們可以采用一個折中的方案:我們對480px寬的設計稿進行還原,但是頁面卻做成320px寬(使用background-size來對圖檔進行縮小),然後,讓頁面自動按照比例縮放。這樣一來,低密度的手機有滾動條(這種手機基本上已經沒有人在用了),中密度的手機會浪費一點點流量,高密度的手機完美呈現,超高密度的手機輕微失真(超高密度的安卓手機很少)。這種方案的優點非常明顯:隻需要一套設計稿,一套代碼(隻考慮安卓手機的情況)。