CSS 與 HTML5 回應式圖片

隨著 Retina 螢幕的逐漸普及,網頁中對圖片的適配要求也越來越高。如何讓圖片在放大了兩倍的 Retina 螢幕顯示依然清晰,曾經一度困擾著網頁開發者,好在 CSS3 與 HTML5 已經著力在改變這種現狀。那麼到底什麼是回應式圖片呢?

什麼是回應式圖片?

回應式圖片是指:使用者代理根據輸出裝置的解析度不同載入不同類型的圖片,不會造成頻寬的浪費。同時,在改變輸出裝置類型或解析度時,能及時載入對應類型的圖片。

CSS3 回應式圖片

對於很多 IOS 開發者來說可能已經不太陌生了,為了適配 Retina 螢幕,傳統的 CSS3 實現方式是通過載入一張寬高分別放大兩倍的圖片,然後通過 Media Queries 使背景圖片尺寸減小一倍「background-size:50% 50%;」,例如:

.mod .hd h3 {
 background-image:url(HTTP://alibuybuy-img11.stor.sinaapp.com/2013/01/ac30_T10s3JXn4XXXXnbIAn-105-160.png);/* 普通螢幕 */
}

/* ------------- Retina ------------- */
@media only screen and (-o-min-device-pixel-ratio: 2/1), /* Opera */
 only screen and (min--moz-device-pixel-ratio: 2), /* Firefox 16 之前 */
 only screen and (-webkit-min-device-pixel-ratio: 2), /* Webkit */
 only screen and (min-resolution: 240DPI), /* 標準 */
 only screen and (min-resolution: 2dppx) /* 標準 */
{
.mod .hd h3{
 background-image:url(HTTP://alibuybuy-img11.stor.sinaapp.com/2013/01/a8e5_T1947tXmJhXXcCfooh-210-320.png);
    background-size: 105px 155px;
}
}

兩張圖片的對比效果:

在製作@2x圖片時需要注意一些問題:

如果類似上圖一樣是純文字內容的圖片,不要直接從大圖片縮放為小圖片,這樣文字效果會有些失真,這是 Photoshop 渲染的問題。應該調整字型大小,再重新排版。可以直接看看:一淘首頁 的效果。


藍框內是直接縮放圖片大小的效果,紅框內是把字型大小從32號改成16號的效果。

CSS3 Media Queries 中用來定義設備解析度的是 resolution 媒體特性,同時派生出兩個媒體特性,分別是 「min-resolution」和 「max-resolution」。該規範中規定:若查詢 Non-Square Pixels (專業術語,指高度與寬度不等的圖元,可以理解為「非正方形圖元」。電腦螢幕上及高清晰度視訊訊號中的圖元是正方形的(圖元寬高比為 1:1)。標準清晰度數碼視訊訊號中的圖元都不是正方形的。例如:NTSC制式的圖元高度大於寬度,而PAL制式的圖元寬度則大於高度。)設備,在「min-resolution」查詢中指定的值必須與最稀疏尺寸進行比較,在「max-resolution」查詢中必須與最密集尺寸進行比較。對於「resolution」(沒有「min-」或「max-」首碼)從不查詢 Non-Square Pixels 設備。另外在 CSS image Level 3「image-resolution」屬性中定義了一些單位,比如「dppx」,各瀏覽器支援情況如下:

 

<tbody>

特性 Chrome Firefox (Gecko) IE Opera Safari (WebKit)
基本特性 不支援「1」「4」 3.5 (1.9.1) 「2」 9 9.5 不支援 「1」「4」
dppx 「4」 16.0 未知 12.10「3」 「4」

 

需要注意幾點:

  1. 「-o-min-device-pixel-ratio」的取值是分數比如「2 /3」,Demo,詳見:Opera Dev 的文章
  2. Firefox 16 之前版本是「min–moz-device-pixel-ratio」,min 後面有兩個「-」。
  3. 1dppx 相當於 96DPI。

顯而易見,通過 Media Queries 來實現「回應式圖片」還是很麻煩,CSS 代碼的可維護性不高,有一些 hack 的味道。我們更期望一種原生的語法來選擇不同的圖片,值得慶倖的是 CSS Image Level 4 中就實現了這種原生語法的「image-set」。

「image-set」語法:

<image-set> = image-set( [ <image-set-decl>, ]* [ <image-set-decl> | <color>] )
<image-set-decl> = [ <image> | <string> ] <resolution>

那麼上面的例子我們可以改為:

background-image:url(HTTP://alibuybuy-img11.stor.sinaapp.com/2013/01/ac30_T10s3JXn4XXXXnbIAn-105-160.png);/* 普通螢幕 */
background-image: -webkit-image-set(
 url(HTTP://alibuybuy-img11.stor.sinaapp.com/2013/01/ac30_T10s3JXn4XXXXnbIAn-105-160.png) 1x,
 url(HTTP://alibuybuy-img11.stor.sinaapp.com/2013/01/a8e5_T1947tXmJhXXcCfooh-210-320.png) 2x);/* Retina */

這裡的單位「x」等同于「dppx」,將來是否統一還有待進一步討論。注意 Webkit 目前只實現了 url() 形式的取值,color、*-gradient() 等暫不支援,而且「x」取負值似乎也是合法的。

以下是一些常見行動裝置的「min-device-pixel-ratio」值:

-webkit-min-device-pixel-ratio: 1.0

  • 所有非 Retina 的 Mac
  • 所有非 Retina 的 iOS 設備
  • Acer Iconia A500
  • Samsung Galaxy Tab 10.1
  • Samsung Galaxy S
  • 其他設備

-webkit-min-device-pixel-ratio: 1.3

  • Google Nexus 7

-webkit-min-device-pixel-ratio: 1.5

  • Google Nexus S
  • Samsung Galaxy S II
  • HTC Desire
  • HTC Incredible S
  • HTC Velocity
  • HTC Sensation

-webkit-min-device-pixel-ratio: 2.0

  • iPhone 4
  • iPhone 4S
  • iPhone 5
  • iPad (3rd generation)
  • iPad 4
  • 所有 Retina displays 的 Mac
  • Google Galaxy Nexus
  • Google Nexus 4
  • Google Nexus 10
  • Samsung Galaxy S III
  • Samsung Galaxy Note II
  • Sony Xperia S
  • HTC One X

HTML5 回應式圖片

CSS「image-set」 解決了背景圖片的回應式問題,但是 HTML中的 img元素怎麼辦呢?正當我一籌莫展的時候,2011年11月 @brucel 提出了HTML5 的一個解決草案:

<picture alt="">
<source src=hires.png media="min-width:800px">
<source src=midres.png media="min-width:480px">
<source src=lores.png>
<!-- 不支援的瀏覽器降級處理 -->
<img src=midres.png alt="">
</picture>

于此同時,其他的一些想法如雨後春筍般湧現出來,於是 W3C 社區討論群組 Responsive Images Community Group 應運而生。最新的規範在這裡:HTTP://picture.responsiveimages.org/ 。截止本文發佈時間,最近一次更新是 2013年1月7日,規範示例:

<picture width="500" height="500">
<source media="(min-width: 45em)" srcset="large-1.jpg 1x, large-2.jpg 2x">
<source media="(min-width: 18em)" srcset="med-1.jpg 1x, med-2.jpg 2x">
<source srcset="small-1.jpg 1x, small-2.jpg 2x">
<img src="HTTP://www.alibuybuy.com/posts/small-1.jpg" alt="">
<p>Accessible text</p>
</picture>

可以看到這裡的「srcset」屬性類似「image-set」,通常情況下,「srcset」裡面的資源是具有 fallback 特性的,也就是說第一個圖片資源無法載入的時候可以跳過載入後面的備用資源。

但是 Apple 的 eoconnor 提出的方案是這樣的:

<img src="HTTP://www.alibuybuy.com/posts/foo-lores.jpg"
 srcset="foo-hires.jpg 2x,
    foo-superduperhires.jpg 6.5x"
 alt="decent alt text for foo.">

誠然,任何一個新標準的提出,都會存在各種不同的聲音,這是好事,作為網頁的最終開發者其實並不太關心實現語法。有任何問題大家也可以直接到 HTML5 中文興趣小組參與討論。

小結

本來想把新年的第一篇文章寫的歡樂一些,不過貌似沒啥槽點。HTML5 回應式圖片的草案還剛剛開始,但是前景還是很美好的。目前我們能做的就是在CSS 中使用「image-set」屬性值,因為目前大部分 Retina 螢幕的設備的瀏覽器都是基於 Webkit 內核的,如果有特殊的需求可以使用 Media Queries。

非常感謝 kenny 對本文排版細節提出的 14 條建議,本文排版遵循:

  • 使用繁體中文引號 「」代替簡體中文「「」」引號;
  • 中英文混排時英文首尾各加一個空格。

來源:HTTP://ued.taobao.com/blog/2013/01/css-and-html5-adaptive-images/

特別注意:本站所有轉載文章言論不代表本站觀點,本站所提供的攝影照片,插畫,設計作品,如需使用,請與原作者聯繫,文章轉自alibuybuy

Comments are closed.