開始使用 <picture> 元素
響應式網頁設計太棒了,它改變了我們向手機端使用者呈現內容的方式,無論使用者使用何種尺寸的手機,我們都能夠為其提供定製化的體驗。響應式網頁設計使用起來很靈活,也容易上手。然而,如果沒有正確使用,它會對網頁效能帶來負面影響。
用於在 PC 端展示的圖片對於手機來說太大了。我們知道,在手機裝置上大尺寸高解析度的圖片會大大降低頁面載入效能。響應式設計和非固定圖片(fluid image)在保證正確顯示的同時,也保證大圖片在頁面顯示的效能大大提高。Tim Kaldec 對響應式圖片的研究表明,使用響應式圖片策略最多可以減少圖片72%的負擔。72%,這是一個相當大的數量。
過去這些年裡,出現了一些響應式圖片解決方案,開發人員也習慣了使用這些方案來解決響應式圖片問題。但都現在看來,這些方法都有一點hacky的味道。這就是 <picture> 元素被引入的原因。
<picture> 元素作為一種向不同裝置輸出高效能圖片資料的客戶端解決方案,目前已經納入 WHATWG HTML 規範 。為了向大家展示 <picture> 元素的強大,我們一起來看一個簡單的例子。
1 2 3 4 5 6 7 |
<picture> <source media="(min-width: 1024px)" srcset="dest/1024/tiger.jpg"> <source media="(min-width: 640px)" srcset="dest/640/tiger.jpg"> <source srcset="dest/320/tiger.jpg"> <img src="dest/640/tiger.jpg" alt="This picture will load on browsers that don't yet support the element."> <p>This is some accessible text.</p> </picture> |
瀏覽器在解析上面的 HTML 語句時會根據裝置的螢幕解析度來選取大小最合適的圖片。點選這個連結觀看實際效果。
從上面的 HTML 程式碼可以看到, <picture> 元素由一組 <source> 標籤組成。<source> 標籤裡面宣告瞭裝置的視口(viewport)寬度以及與之相應尺寸的圖片。這樣不同裝置上的瀏覽器就可以根據這些資訊選取最適合的圖片源。這是一個出色的解決方案,因為所有的操作都是在客戶端完成,開發者對展現給使用者的圖片具有控制權。
值得一提的是,通過設定 <img> 標籤的 srcset 屬性和 size 屬性也可以達到相同的效果。這兩個屬性由 <img> 標籤和 <source> 標籤擴充套件而來,提供一系列圖片資源和相應的圖片大小。瀏覽器根據這些資訊來選取最合適的圖片。假如你不考慮圖片的藝術美感,可以使用這種方法。
1 2 3 |
<img src="dest/320/tiger.jpg" srcset="dest/1024/tiger.jpg 1024w, dest/640/tiger.jpg 640w, dest/320/tiger.jpg 320w" alt="A TIGER!!!"> |
如果你還想了解更多關於 <picture> 元素的歷史和起源,推薦你讀這篇文章。
處理圖片
<picture> 元素在網頁效能上效果顯著,同時也給我們帶來很大的便利,問題是,我們怎樣去生產這些不同大小的圖片呢?假如你需要多份不同的圖片,怎樣得到這些圖片呢?慶幸的是,有一種簡單的方法可以解決這個問題。
使用 Grunt 響應式圖片外掛可以自動處理、剪裁圖片。假如你對 Grunt 任務不熟,也不知道怎樣將它引用到你的工程,請參考我之前發表的這篇博文。 Grunt 官網也提供了非常好的教學資源幫助你立刻開始使用它。
npm install grunt-responsive-images –save-dev
配置好 Grunt ,並且保證它能在你機器上執行之後,開啟你的網站,在命令列裡輸入以下命令來下載相應的包。
npm install grunt-responsive-images –save-dev
接下來你還需要安裝 ImageMagick 或 GraphicsMagick 命令列工具,然後配置 gruntfile.js 檔案。下面是一個引數配置例子,有很多配置選項,可以根據實際需求設定不同的引數。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
grunt.initConfig({ responsive_images: { myTask: { options: { sizes: [{ width: 320, height: 240 },{ name: 'large', width: 640 },{ name: "large", width: 1024, suffix: "_x2", quality: 60 }] }, files: [{ expand: true, src: ['assets/**.{jpg,gif,png}'], cwd: 'test/', dest: 'tmp/' }] } }, }) |
通過上面的引數設定,圖片將生成 320 畫素, 630 畫素和 1024 畫素的圖片,每種畫素的圖片將放在不同的目錄裡。
現在,可以處理圖片了。在命令列中執行 Grunt 命令,這個時候,可以看到目錄下會新增加三個目錄,每個目錄中已經存在裁剪好了的圖片! Hooray !
如果還在想什麼工具可以自動幫助你生成相關的 HTML 標籤的話,這個 Grunt 外掛能替你做這些苦差事。把這個外掛和 Grunt responsive images 外掛結合起來用,會給你帶來更多意外驚喜。
OLDER BROWSERS
關注瀏覽器的新特性的同時,也要兼顧到老版本的瀏覽器。目前,只有 Chrome 38 和 Opera 支援 <picture> 元素。好訊息是, <picture> 元素已經正式被 WHAT working group 接受,逐漸所有現代瀏覽器都會支援這個標籤。通過 caniuse.com 可以查到,你喜歡的瀏覽器現在是不是支援它。
幸好,現在有一個外掛可以解決大部分傳統瀏覽器不支援 <picture> 元素的問題。 Filament Group 的團隊開發出 picturefill.js 這個檔案,這個外掛可以使不支援 <picture> 元素的瀏覽器解析這個標籤以及標籤相關的屬性。這意味著,你今天就可以開始使用 <picture> 元素了!
要使用這個外掛,你需要在你的頁面中新增這個 JavaScript 檔案。
1 2 3 4 5 6 7 8 9 10 11 12 |
<picture> <source media="(min-width: 1024px)" srcset="dest/1024/tiger.jpg"> <source media="(min-width: 640px)" srcset="dest/640/tiger.jpg"> <source srcset="dest/320/tiger.jpg"> <img src="dest/640/tiger.jpg" alt="This picture loads on non-supporting browsers."> <p>Accessible text.</p> </picture> <script> // Picture element HTML5 shiv for older browsers document.createElement( "picture" ); </script> <script src="picturefill.min.js" async></script> |
再補充一句,這個外掛和 picture 標籤的功能是一樣的。點選這個連結可以看到例項效果。在 Responsive Images Community Group 網站上還有很多例子。
附註
我第一次使用 picture 標籤的時候,出現了這個錯誤:
“<source src> with a <picture> parent is invalid and therefore ignored. Please use <source srcset> instead.”
這次錯誤提示資訊非常明確,在引用圖片資源時不要使用 src 標籤,使用 srcset 標籤就可以了。