在當前響應式設計和自適應設計的流行下,很多web 應用往往都兼容手機、平板和PC,其中一個讓人比較頭痛的問題就是圖片的加載了。不同平臺顯然不可能用同一張大的圖片,這樣子不但浪費手機流量、影響網站載入速度并且在小屏幕下會很不清晰。讓瀏覽器根據分辨率自動識別圖片是最好的方法。響應式圖片和多媒體是響應式網站的三大基礎重點之一。表面上看這是一件非常簡單的事情,只要把圖片元素的高、寬屬性值都移去,然后設置max-width屬性為100%即可。不過在這么做之前還需要考慮很多情況。設計響應式圖片的難點去年Filament Group在重構Boston Globe網站時也是通過設置max-width屬性使得圖片能夠自適應。不過這么做的前提是你必須要創建一幅盡可能高分辨率的圖片。除非是真正需要那么大的圖片,否則這就是一種浪費。智能手機和平板電腦通過移動網絡瀏覽該網站時,并不需要那么大尺寸的圖片——大尺寸圖片意味著大的帶寬。即使不考慮帶寬也應該考慮同一幅圖片以不同尺寸顯示時的問題,在圖片原始大小是300px的情況下以1000px尺寸顯示無疑會損失很多的細節。最好的解決方法則是使用大圖的一部分或者干脆完全用不同尺寸的圖片。同時我們不應當忘記高分辨率的顯示需求。Apple 設備的retina技術顯示圖片要求更多的圖片,考慮到其他設備也會跟隨Apple的高分辨率顯示技術(不過可能顯示的像素尺寸不同)。我們若將所有不同尺寸的圖片都預加載進來,此乃飲鴆止渴之舉,萬不可取——畢竟我們的目標只是是減少帶寬而非增加。我們需要更強大的能力為不同的設備環境提供合適的圖片和多媒體。3種解決方法目前已經有幾種備選的解決方案解決這些問題,Chris Coyier在他的博文里歸納總結如下:創建一個新的(HTML)元素創建新的圖像格式使用特定技術手段下面我們一一簡述各種方案。創建新元素(或屬性)該方法已經在使用了,不過在使用方式上存在一些爭議。這些爭議主要來自兩方面:業界的web開發者和瀏覽器制造者。web開發者提議創建一個新的picture元素(類似HMTL5中的video這樣的元素),該元素中包含其他的圖片源,示例代碼如下:<picture alt="image description">
<source src="/path/to/medium-image.png" media="(min-width: 600px)">
<source src="/path/to/large-image.png" media="(min-width: 800px)">
<img src="/path/to/mobile-image.png" alt="image description">
</picture>
其中的img元素是默認情況下顯示的圖片源,在其上面的兩個source元素則是在特定媒體查詢(media queries)條件下顯示的圖片——這也是開發者所喜歡的一種解決方案。Scott Jehl針對圖片元素創建了polyfill項目,就是利用了這種思想,你現在可是就可以使用它了。 <span data-picture data-alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
<span data-src="small.jpg"></span>
<span data-src="medium.jpg" data-media="(min-width: 400px)"></span>
<span data-src="large.jpg" data-media="(min-width: 800px)"></span>
<span data-src="extralarge.jpg" data-media="(min-width: 1000px)"></span>
<!-- Fallback content for non-JS browsers. Same img src as the initial, unqualified source element. -->
<noscript>
<img src="small.jpg" alt="A giant stone face at The Bayon temple in Angkor Thom, Cambodia">
</noscript>
</span> 瀏覽器開發者則是通過給img元素標簽增加srcset屬性來解決此問題的,功能一樣,然而直覺上不好理解。<img src="path-to-default-image.jpg" alt=""
srcset="path-to-default-image.jpg 600w 200h 1x,
path-to-another-image.jpg 600w 200h 2x,
path-to-a-third-image.jpg 200w 200h">
以srcset的一個值為例講解:path-to-another-image.jpg 600w 200h 2x? path-to-another-image.jpg 是不言自明的,當符合下述條件時就使用該 圖片? 依據media queries要求,設備最小尺寸為600w和200h? 瀏覽器有以2x像素密度顯示的能力因此這里所表達的意思是,當瀏覽器能夠處理2x像素圖片,且設備至少是600px寬、200px高的情況下,使用此圖片源顯示。此種解決方法從瀏覽器開發者角度看是非常合適的,畢竟能夠讓瀏覽器自己通過算法獲取設備的兼容性和像素密度。上述兩種方法各有優點,此篇文章也并未認為其中一方的方法要好于另一方的。如何你想了解更多的討論細節,可以點擊鏈接。作為網站開發者我比較喜歡用picture元素,然而使用srcset屬性的img元素有更強的兼容性。這場討論現今仍在進行,大多數人希望能夠找到一種吸取兩者優點的方法。這段時間我恰巧收聽了一組討論上述問題的播客,其地址如下:? SitePoint Podcast #168: Secret Src with Jeremy Keith? The Web Ahead: Responsive Images with Mat Marquis創建新圖像格式這種方法更容易解釋了,Christopher Schmitt 呼吁針對響應式圖片創建一種新的圖像格式。該新的格式包含了幾種不同大小版本的圖片。比如100k的文件里有75k的版本、20k的版本和5k版本的圖像。從某種意義上講就像.mp3格式那樣,該種文件格式既存儲了歌曲也存儲了歌曲的meta信息。這里的圖像版本信息就好比MP3的meta信息,然后依據既定的一組標準選擇該里面最為合適設備的一個圖片版本。這種解決方法的缺點是必須放棄一些可控性能。新文件格式會自行決定什么時候使用哪個版本的圖片,只是當然對于不支持該種格式的瀏覽器也失去了后向兼容。其他技術上述的方法固然簡單,然而面前還未正式標準。如果你想為不同的設備提供不同的合適圖片,可以考慮使用下列多種方法之一。很多博文都將在一節篇幅中敘述所有這些技術。我們可以模仿Filament Group的做法,他們針對Boston Globe網站提供響應式圖片的做法如下:? Markup —默認是用img元素標簽? Javascript — 決定viewport的尺寸,將存儲在cookie中的相關信息傳給服務器,而后再改變img標簽的src屬性。.? Server — 獲取初始圖片請求,讀取cookie,如果不是移動終端設備則返回1x1大小的空白占位圖。然后等待JS腳本將真正的圖片填充進去。這種方式并沒有想期望中那樣完美,卻也給出了一種解決思路,可以讓其他人在上面繼續發揮。許多后續的方法其思路與此相仿,默認都是提供移動端圖片,繼而嘗試探測設備屬性后再發送合適大小的圖片。Chris Coyier 和 Christopher Schmitt創建了一張電子表格,你可以據此作為你項目中選用何種技術的參考。Chris也基于這張電子表格寫了一篇技術文章回答大多數疑問——你應當使用哪種自適應圖片技術?我在上面所提及的技術也許給你一些大概的印象,你不妨看看Chris的那篇文章和電子表格,以了解這些技術的細節實現。Foresight.js是在給服務器發送請求之前用JavaScript去探測該設備是否支持高分辨率圖片,同時也探測該設備所在網絡的網速。依據探測結果才向服務器請求合適的圖片資源。Images redux使用空白的1x1GIF(轉成base64格式)。它將該圖片設置為所有圖片的初始背景或占位符,提供更好的用戶體驗。由于圖片是依據CSS設置的,所以可用media queries改變響應樣式。Image above via CSS TricksAdaptive images 項目靈感來源于Filament Group重構Boston Globe網站的工作。不過它需要諸如Apache 2, PHP 5.x, 和 GD 庫等的支持,好在這些工具都比較常用。該技術首先在cookie中保存屏幕分辨率,然后決定使用哪種合適的圖片尺寸。如果JavaScript和cookie被禁用了,它就檢測user agent字符串。如果發現“Mobile”字符,就發送最低分辨率(定義在$resolutions里)的圖片給終端,否則就默認假設你使用大設備終端并發送高分辨率圖像。HiSRC是一個jQuery插件,它能探測網絡速度與分辨率,默認情況下只提供最小的圖片。但是HiSRC能夠探測設備更多的能力,然后提供更多不同類別的圖像。Jeremy Keith在文章里提出Conditionally Loading Content的方法,也是關于如何向不同設備提供不同圖像。由于探測了viewport的寬度,Jeremy其實是提供了自定義的解決方案。Jeremy在后續的文章中也提出了Conditional CSS方法,展現了如何在前人的基礎上進行改進的方案。總結圖片響應式化的第一步是讓它自適應,移除高、寬屬性然后設置max-width屬性為100%。然而這并不能從根本上解決問題。主要的問題在于,那樣做會不得不創建一張大尺寸高分辨率的圖像,很明顯這種圖片并不利于移動終端設備的接收。一種有效的解決方法是使用新的HTML語法,告知瀏覽器應當使用那張合適的圖片;也許我們應當創建新的圖像格式,那樣也能解決現在的問題。不過為今之計,還是不得不借助現有的技術實現圖像響應式。這些技術的思想是提供移動端版本的圖像,然后探測其是否還能處理更大的圖像,如果可以則使用Javascript腳本將更大的圖片替換默認的小圖。圖片響應式和響應式設計其實還有很長一段路要走,我還會繼續就這個話題展開敘述,下次應該主要涉及矢量圖像方面的內容,由于這方面的內容和此篇文章主題關系甚微,所以就單獨展開。