此像素非彼像素

本文由99根據Patrick H. Lauke的《A pixel is not a pixel is not a pixel》所譯,整個譯文帶有我們自己的理解與思想,如果譯得不好或不對之處還請同行朋友指點。如需轉載此譯文,需註明英文出處:http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html,以及作者相關信息

作者:Patrick H. Lauke

譯者:99

本篇文章主要解釋了CSS像素跟設備像互的區別,媒體查詢跟Viewport在識別設備像素上的應用,以及iPhone的分辨率增加後對我們Web前端的影響。

在譯這篇文章時,文章很多知識引用了神飛的《移動端webapp開發必備知識》和www.MyException.Cn的《什麼是viewport,爲啥需要viewport》。在此特向作者表示衷心的感謝。

譯者:——99

昨天,來自John Gruber的文章中談到最新的蘋果手機提升了像素密度(960X640替代了480X320),並分析了蘋果這麼做的原因,他同時提出了一個問題,這對Web開發者會有什麼影響呢?

我最近在深入研究移動端跨瀏覽器的寬高表現,可以這麼說,在99%的情況下,蘋果此舉不會對web開發者有任何影響。

但剩下的1%就比較蛋疼了,不過我期待蘋果可以像android一樣採用一箇中間過渡像素層來解決此問題。(John指出)在Android中存在這樣的一個層。

首先我要申明一點,對於web開發者來說“標準尺寸”是沒啥用處的,所以我忽略了這個,而且我也不會討論顯示的細節以及其他一些複雜問題,因此我對其中的一些概念描述的可能不是很專業,在此表示抱歉。

Web開發者到底需要啥

在開始下面的內容之前,大家先了解一下CSS Pixels與Device Pixels之間的區別:

  1.  CSS pixels: 瀏覽器使用的抽象單位, 主要用來在網頁上繪製內容。
  2.  device pixels: 顯示屏幕的的最小物理單位,每個dp包含自己的顏色、亮度。

——99

我確信對於web開發者來說,他們需要的是“css像素”,即類似width:300px跟font-size:14px 這類css語句中的px.

Css中的px跟設備自身的px是沒什麼關係的,即使將來出現了所謂“中間過渡層”,結果也是一樣的。這是專門爲web開發者提出的一個抽象概念。

通過頁面縮放這個過程,我們可以很清楚的明白這個道理。如果我們放大頁面,一個給了width:300px的元素會佔據屏幕更大的空間,當然測量時會佔據更多的設備(物理)像素。而css中的像素始終是300px。放大效果即是儘可能的擴展每一個css像素,使其佔據更多的屏幕空間。

當縮放比率爲100%時,一個css像素與一個設備像素是相同的(未來提供的中間過渡層,會代替“設備像素”)。下面圖片表示當前狀態時css像素與設備像素是重疊的。

pixel

(要提醒大家的是,縮放比例100% 在web開發中是沒啥意義的,縮放級別對我們也沒啥意義。我們需要知道的是當前有多少像素在適配屏幕!)

下面兩張圖詮釋了當我們縮放頁面時發生了啥。第一張圖,用戶縮小頁面,注意觀察淺色像素塊(css像素)跟深色像素塊(設備像素)。此時css像素變小,一個設備像素可能覆蓋了多個css像素。

第二張圖片跟上面正好相反,用戶放大頁面,此時css像素變大,因此一個css像素覆蓋了多個設備像素

pixel

因此,元素仍然是300px(css像素) 而此時元素覆蓋了多少的設備像素,是由當前的縮放比例決定的。

你可以通過在iphone上計算screen.width跟window.innerWidth的比來得到這個比例。這裏會出現很多惱人的兼容性問題。除此之外 web開發者不需要對這個比例下太多心思,還是要注意像素是怎麼適配屏幕的。

Window.innerWidth這裏代表的視窗寬度,Screen.width 代表的屏幕分辨率。

這裏大家可以做個實驗就明白了,大家可以在網頁100%的時候打印下screen.width跟window.innerWidth會發現是1:1。而我們利用瀏覽器的縮放功能,縮小網頁時,發現screen.width不變,window.innerwidth變大,意思是同樣的屏幕可以容納的css像素更多了,放大網頁正好相反!

——99

以上原理是不會改變的。因此以前在iphone上顯示完美的網頁,到了高設備像素的iphone上可能就會變得面目全非,這也是蘋果極力想要避免的。

因此網頁仍然會按照980px來渲染,但是佔了多少個設備像素。。天知道。。

那些比較蛋疼的東西

有兩個比較麻煩的東西:媒體查詢的"device-width"和html標籤中的"<meta name="viewport" width="device-width" / >"。這兩個都與設備像素有關係的,但與css像素沒關係,因爲他們都是根據頁面展現出的內容來定義的,而不是內部是什麼css決定的。

媒體查詢

device-width 這個媒體查詢可以測量設備像素。Width這個媒體查詢可以測量頁面的總寬度,但這個是css像素。這個數在iphone上一般是980以上,原因我會在後面解釋。

pixel

Device-width這個媒體查詢以下面方式來定義

div.sidebar {
  width: 300px;
}

@media all and (max-device-width: 320px) {
  // styles assigned when device width is smaller than 320px;
  div.sidebar {
    width: 100px;
  }
}

通過css定義寬度,sidebar現在的寬度是300px(css像素),但經過媒體查詢,當設備寬度小於320像素時(設備像素),觸發條件,sidebar的寬度變爲100px(css像素)(還跟得上不,確實比較繞)。

CSS3中的Media Queries增加了更多的媒體查詢,同時你可以添加不同的媒體類型的表達式用來檢查媒體是否符合某些條件,如果媒體符合相應的條件,那麼就會調用對應的樣式表。換句簡單的說,“在CSS3中我們可以設置不同類型的媒體條件,並根據對應的條件,給相應符合條件的媒體調用相對應的樣式表”。

有關於Media Queries介紹和使用可以參考下面:

  1.  CSS3 Media Queries
  2.  iPads和iPones的Media Queries
  3.  CSS3 Media Queries模板
  4.  使用em單位創建CSS3的Media Queries
  5.  Responsive設計和CSS3 Media Queries的結合

——大漠

同時理論上你可以利用媒體查詢來根據釐米與英寸識別屏幕。(@media all and (max-device-width: 9cm))。但很不幸絕大多數情況下都不支持,包括iphone。這是因爲很多情況下,物理尺寸(比如英寸)會被系統“翻譯”爲css尺寸。我測試過 大部分瀏覽器一英寸會被認爲是96px(css像素)。因此上述根據物理尺寸進行的媒體查詢,結果是沒有什麼參考價值的。

這裏的物理尺寸跟設備像素比有專門的術語叫做dpi。

PPI,有時也叫DPI,所表示的是每英寸所擁有的像素(pixel)數目,數值越高,即代表顯示屏能夠以越高的密度顯示圖像。(注:這裏的像素,指的是device pixels。)

注意,這裏仍然是設備裏的參數,與css像素是沒有任何關係的!但是mediaquery卻認成了css像素!

——99

<meta>標籤

關於meta標籤的介紹可以參考《<meta>》一文,但我們主要應用的是viewport標籤,可以參考《Using the viewport meta tag to control layout on mobile browsers》一文。

——99

大多數情況下 <meta name="viewport" width="device-width"> 這個標籤比上面要給力的多。viewport起源於apple,但現在被絕大多數移動瀏覽器所支持。這個標籤的寫法可以讓你的layout viewport完全適配設備寬度

layout Viewport到底是啥呢?

這裏文章寫的比較簡單,但是不好翻譯。我大概給大家講講viewport。

兩個概念,visual viewport跟layout viewport.

這裏visualviewport可以認爲是設備自己的寬度,那麼注意,當你打開一個960px設計的網頁時,手機會根據css中的百分比進行縮放。比如總長960的頁面,導航條是20%。(實際解析出來就是192px)但是你不可能每個屬性都是百分比吧,比如文字大小。

那麼我用320px屏幕打開,導航條就成了64px了,但是我的字體大小是12px啊,完了,本來能顯示很多漢字的(192/12)現在只能顯示64/12個漢字了。

Apple找到了一個辦法:在移動版(iOS)的Safari中定義了viewport meta標籤①,它的作用就是創建一個虛擬的窗口(viewport),而且這個虛擬窗口的分辨率接近於桌面顯示器,Apple將其定位爲980px②。

①除此之外不同移動瀏覽器廠商也有不同的解決方案,例如UCweb就是使用中間件技術。

②不同的瀏覽器廠商對於layout viewport的大小定義不同

  1.  Safari iPhone: 980px
  2.  Opera: 850px
  3.  Android WebKit: 800px
  4.  IE: 974px

以一代iphone下的Safari來說就是:

在iphone的320px物理屏幕上——視覺窗口(visual viewport),創建出了一個980px的虛擬窗口——佈局窗口(layout viewport),在視覺窗口(visual viewport)中我們可以拖動橫向豎向滑動條或者放大縮小網頁,來達到最佳的瀏覽效果(類似桌面瀏覽器);而佈局窗口(layout viewport)用來配合CSS渲染布局,例如當我們設置一個容器的寬度爲100%時,這個容器的實際值爲980px而不是320px。如此一來大部分 網頁就能以縮放的形式正常的顯示在手機屏幕上了。

但是。。。。。。。。。。。。道高一尺魔高一丈,當我們“爲了”解決手機端的問題,而特意製作了320px的頁面時,悲劇發生了。。

因爲iphone的layout viewport默認爲980px,導致專爲其優化的320px寬的頁面只能以縮放的方式顯示,(可以想象在你的瀏覽器裏打開一個320px的頁面的情景。。。)這時就需要對viewport進行設置

<meta name=”viewport” content=”width=device-width, initial-scale=1.0, user-scalable=no”/>

將viewport定義爲:寬度爲設備寬度,初始縮放比例爲1倍,禁止用戶縮放。

這其實是故意捨棄了viewport的做法,大家一定要明白這個道理。給大家理一下:

普通的頁面(960,980)顯示很差? Apple去開發viewport,我們要求設計師設計320px的網頁

好了,apple開發完viewport了,以前的爛網頁能看了,這時候,我們換上320px的網頁,我擦,怎麼變的這麼小了!

變回來!content=”width=device-width 就是這個過程。。。

更多viewport的知識,可以參考《Using the Viewport》和《響應式新首頁設備適配(Device Adaptation)小結

——99

一般來說layout Viewport要比設備屏幕大。 下面那張圖讓網頁直接覆蓋在屏幕上,大家可以看看視窗有多大。

pixel

當我們使用<meta name="viewport" width="device-width">後,頁面視口被強制伸縮爲屏幕寬度,比如320(iphone)。

這決定了你的網頁視口會以怎樣的寬度適配屏幕。當你的網頁跟下圖一樣,設計成320px的寬度時,你又不使用width跟meta標籤,頁面就會被縮放了。如下圖:

pixel

這種屏幕當然沒法閱讀了。如果你想讓字體大小適配屏幕, meta標籤就要出場了。當你增加這個標籤後,視口會自動調整到屏幕大小(比如iphone會變成320px)

pixel

Apple的改變

我們回到開頭的問題,當apple的屏幕像素增大後,會對我們上文提到的媒體查詢跟meta標籤造成什麼影響。我當然不確定,但我希望不會對web開發造成影響。

<meta>標籤

Meta標籤很好說,這本來就是蘋果發明的標籤,爲了讓原始網頁適配蘋果的屏幕,而且已經推進給web開發者了。這意味着蘋果不會改變meta標籤識別出來的設備像素值了。

事實上,nexus one 另闢蹊徑。在豎屏時屏幕寬度爲480px,而應用meta標籤識別出的屏幕寬度卻是320px,是實際屏幕寬度的2/3

爲什麼會出現nexus的問題呢?

width=device-width

其實這個屬性&值很有意思,字面意應該是viewport寬度等於設備寬度,但在實際中不同的瀏覽器都給出了個定值:320px;這個值還是源於 Apple,因爲早期iphone的分辨率爲320px × 480px,大量爲iphone量身定製的網站都設置了viewport:width=device-width,並且按照寬度320px來設計製作,所 以其他瀏覽器加入viewport支持時爲了兼容性也將device-width定義爲了320px。

——99

如果我理解正確的話,這就是爲什麼nexus顯示網頁的時候缺失了1/3像素的原因。這與nexus對meta標籤的解釋是一致的。(因爲認成320了。。)

因此谷歌爲了解決這個問題,插入了一箇中間層。這個層“層如其名”: “與設備無關的層”。這個層在實際屏幕與我們開發的css網頁之間。

我期望iphone也會採取nexus的方案,建立中間層,保持meta標籤識別出來仍然是320px(實際像素的一半)(作者的意思這樣我們就不用改網頁了)

媒體查詢

Device-width仍然是問題重災區。儘管nexus識別出480px作爲設備寬度,我仍然覺得320px會更適合。我們且看apple是怎麼辦的。

最根本的問題是 設備獨立像素(dips)在媒體查詢中的繼續應用。我們當然期待這東西的應用了,因爲設備尺寸我們並不關心,我們只是想了解我們從屏幕上呈現的東西,dips應該很適合這個。

爲什麼dips有這個作用呢?這裏要引入一個概念。

window.devicePixelRatio是設備上物理像素和設備獨立像素(device-independent pixels (dips))的比例。

公式表示就是:window.devicePixelRatio = 物理像素 / dips

詳細的大家可以參考:《設備像素比devicePixelRatio簡單介紹》一文。

——99

不幸的是nexus依然故我,media query查詢出來的設備寬度仍然是480px而不是320px。但我覺得apple會爲web開發者解決這個問題的。

因此結論很明顯,meta的仍然故我,媒體查詢的可就要掂量下了。

譯者手語:整個翻譯依照原文線路進行,並在翻譯過程略加了個人對技術的理解。如果翻譯有不對之處,還煩請同行朋友指點。謝謝!

如需轉載煩請註明出處:

英文原文:http://www.quirksmode.org/blog/archives/2010/04/a_pixel_is_not.html

中文譯文:http://www.w3cplus.com/css/A-pixel-is-not-a-pixel-is-not-a-pixel.html

原文鏈接: http://www.w3cplus.com/css/A-pixel-is-not-a-pixel-is-not-a-pixel.html
發佈了1 篇原創文章 · 獲贊 11 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章