聲明:此篇文章由靠譜男青年獎得主根據(jù)Pearl Chen的英文文章《Built-in Browser Support for Responsive Images》進行翻譯犹菇,整個譯文帶有我自己的理解拆座,如果譯得不好或不對之處還請指點欲间。
如需轉(zhuǎn)載此譯文脾歇,需注明英文出處:http://www.html5rocks.com/en/tutorials/responsive/picture-element/ 以及作者累铅、譯者相關(guān)信息
——作者:Pearl Chen
——譯者:靠譜男青年獎得主
介紹<picture>標簽
<picture>
標簽提供了瀏覽器原生支持的圖像資源加載方法任连。web開發(fā)者們無需在使用CSS和Javascript Hacks來在響應(yīng)式設(shè)計中處理圖像,而使用這種設(shè)計方式創(chuàng)造出的產(chǎn)品的使用者們會從這個瀏覽器底層優(yōu)化的圖像資源加載方式獲益——特別是對于那些網(wǎng)絡(luò)加載速度很慢的用戶千绪。
隨著srcset
和sizes
這兩個<img>
標簽的新屬性的加入充易,<picture>
標簽使得程序員在選擇加載圖像資源時更具靈活性。書寫明確地的HTML標記荸型,讓瀏覽器去查明接下來這些適應(yīng)情況盹靴,不管是單獨使用還是和其他方法一同使用,從而更好地支持響應(yīng)式設(shè)計瑞妇,就愛哭愛網(wǎng)頁加載速度稿静。加載情況有:
-
基于屏幕方向的選項
這是一個手機設(shè)備還是一個PC端設(shè)備?通過屏幕方向的識別來判斷載入資源圖片辕狰。
-
基于設(shè)備像素比的選項
這個設(shè)備是不是高分屏改备?要針對屏幕的高分辨率去加載更高分辨率的圖像。
-
基于視圖的選項
圖像是否在視圖中采用fixed布局柳琢?那么就使用視圖寬度判斷圖像動態(tài)變化绍妨。
-
基于圖像格式的選項
瀏覽器是否支持其他的圖像格式润脸?如果確實如此柬脸,我們可以選擇加載諸如webp[1]后綴的其他格式圖像。
基于屏幕方向的選項
這應(yīng)該是<picture>標簽在進行響應(yīng)式變化是最常見的一個使用情況毙驯。不去使用一張圖以設(shè)備寬度為標準來進行縮放倒堕,取而代之的解決方案是使用多個圖像,他們中的每一個都是對應(yīng)平臺上最適合的尺寸爆价。
改善了加載表現(xiàn)
當使用<picture>或<img/>標簽的時候,如果使用了srcset
和sizes
屬性垦巴,那么瀏覽器只下載那個最適合當前使用情況的圖片媳搪,這個改進符合瀏覽器語法,而且可以節(jié)省圖像緩存骤宣,改進預(yù)加載能力秦爆。
看一個演示
事實是,網(wǎng)絡(luò)被創(chuàng)造是為了放置小貓照片的憔披。使用<picture>標簽我們可以去模仿小貓適應(yīng)空間的能力等限,無論這個空間是很大還是很小
點擊這個[超鏈接](http://googlechrome.github.io/samples/picture-element/
)打開小貓,并且試著更改你顯示器的寬度來查看小貓是如何跟著瀏覽器寬度進行適應(yīng)的芬膝。
到目前為止我們只是看了一些<piture>可以做到的一些小例子望门。下面來看看語法
<picture>語法
下面的這一串HTML和CSS語句片段就是我們?yōu)榱藢崿F(xiàn)上邊這個demo的所有代碼。
<style>
img {display: block; margin: 0 auto;}
</style>
<picture>
<source
media="(min-width: 650px)"
srcset="images/kitten-stretching.png">
<source
media="(min-width: 465px)"
srcset="images/kitten-sitting.png">
<img
src="images/kitten-curled.png"
alt="a cute kitten">
</picture>
看看锰霜,這里面沒有Javascript代碼筹误,并且也沒有第三方庫。CSS語句僅僅是去控制圖像的放置位置癣缅,不包含設(shè)備查詢代碼厨剪。這意味著你只需要HTML就可以進行圖片的響應(yīng)式開發(fā)。
使用<source>標簽
<picture>標簽沒有自己的私有屬性友存,自適應(yīng)的秘密在于<picture>是被用作<source>標簽的容器丽惶。
<source>標簽是用來加載媒體文件,類似于音頻和視頻爬立,目前他開始對圖片支持钾唬,并且加入了更多的屬性。
srcset(必須的屬性)
- 接受的參數(shù)是單獨一個圖片的文件路徑(比如
srcset = "../../kitten.jpg"
) - 或者是使用逗號隔開的一個路徑列表侠驯,同時在屬性值里加上分辨率表達參數(shù)(比如:
srcset="kitten.png, kitten@2X.png 2x
)抡秆,1x是默認的,所以他在表達式中是被省略的吟策。
查看“使用分辨率表達式來組合路徑”獲得更詳細的使用方法儒士。
media(可選屬性)
- 接受一個有效的媒體查詢語句,和css的
@media
媒體查詢語句一樣(比如:media = "(max-width:30em)"
或者medai = "(min-width):30em"
)
查看之前的"<picture>語法代碼模塊"了解具體使用例子
sizes(可選屬性)
接受一個單獨的寬度表達式(比如:
sizes="100vw"
),或者是你可以放置一個媒體查詢語句和一個寬度表達式(比如:sizes="(max-width: 30em) 100vw"
[2])檩坚。或者是接受一個由逗號隔開的表達式列表(比如:`sizes="(max-width: 30em) 100vw, (max-width: 50em) 50vw, calc(33vw - 100px)[3]),最后一個參數(shù)用作默認設(shè)置着撩。
查看使用"寬度表達式合并"模塊獲得使用方法。
type(可選屬性)
- 接受一個MIME type表達式(比如:
type="image/webp"
或者是type="image/vnd.ms-photo"
等)
查看“加載其他圖像格式”獲得更多使用方法
在最后加上<img/>標簽
目前<img/>標簽經(jīng)過用法升級之后也可以在<picture>標簽內(nèi)部使用匾委,這樣做是為了兼容不支持<picture>標簽的瀏覽器或者是沒有<source>標簽的情況或者是<source>表達式?jīng)]有使用的現(xiàn)實情況拖叙。<picture>標簽內(nèi)的這個<img/>標簽是必需的,如果你忘了加這個標簽?zāi)敲丛陧撁嫔鲜裁炊疾粫@示赂乐,哪怕你加了完整的<source>也一樣薯鳍。
在<picture>標簽中使用<img/>標簽來聲明默認圖片,并且將它作為<picture>的最后一個子節(jié)點挨措,只有在<img/>存在的情況下<source>才會被聲明挖滤、渲染崩溪。同時不要忘了給<img/>增加alt
屬性
使用分辨率表達式來組合路徑
為了保證對于高分辨率屏幕的支持,srcset
屬性支持分辨率倍數(shù)定義如1x斩松,1.5x,2x,3x伶唯。最新的srcset
屬性已經(jīng)同時支持<img/>和<picture>標簽了
下面這個例子支持了三種設(shè)備分辨率:1x,1.5x,2x:
<picture>
<source
media="(min-width: 650px)"
srcset="images/kitten-stretching.png,
images/kitten-stretching@1.5x.png 1.5x,
images/kitten-stretching@2x.png 2x">
<source
media="(min-width: 465px)"
srcset="images/kitten-sitting.png,
images/kitten-sitting@1.5x.png 1.5x
images/kitten-sitting@2x.png 2x">
<img
src="images/kitten-curled.png"
srcset="images/kitten-curled@1.5x.png 1.5x,
images/kitten-curled@2x.png 2x"
alt="a cute kitten">
</picture>
使用寬度表達式合并屬性
谷歌的web開發(fā)最佳實踐手冊已經(jīng)涵蓋了最新的<img/>標簽支持的sizes屬性:
當一個圖片的大小和分辨率是未知的并且有可能是浮動的,那么我們就很難去給他一個適應(yīng)的屬性
不去給圖片一個確切的寬度和分辨率惧盹,取而代之是給<img/>對象增加屬性抵怎,以允許瀏覽器經(jīng)過計算之后改變他的寬度,選擇最確切的一個尺寸進行下載
下面是一個使用sizes的例子岭参,這個圖片永遠只填滿設(shè)備寬度的80%反惕,實現(xiàn)方法是使用secset
屬性來選擇160px、320px演侯、640px姿染、1280px的寬度:
<img src="lighthouse-160.jpg" alt="lighthouse"
sizes="80vw"
srcset="lighthouse-160.jpg 160w,
lighthouse-320.jpg 320w,
lighthouse-640.jpg 640w,
lighthouse-1280.jpg 1280w">
瀏覽器會根據(jù)對應(yīng)的瀏覽器視圖寬度來選擇展示圖片
上邊這個例子,左邊的視圖差不多800px寬秒际,瀏覽器就會加載-640.jpg那副圖悬赏,除非設(shè)備分辨率是2x類型——這樣的花就需要-1280.jpg了
通過加入<picture>標簽,<img/>和<source>標簽都可以使用sizes
屬性了娄徊。
<picture>
<source media="(min-width: 800px)"
sizes="80vw"
srcset="lighthouse-landscape-640.jpg 640w,
lighthouse-landscape-1280.jpg 1280w,
lighthouse-landscape-2560.jpg 2560w">
<img src="lighthouse-160.jpg" alt="lighthouse"
sizes="80vw"
srcset="lighthouse-160.jpg 160w,
lighthouse-320.jpg 320w,
lighthouse-640.jpg 640w,
lighthouse-1280.jpg 1280w">
</picture>
上邊的這個例子里如果瀏覽器的寬度超過了800px闽颇,就會顯示這個帶有陸地的大圖。
加載其他的圖片格式
<source>標簽的type屬性可以用來加載其他格式的圖片寄锐,但這個屬性并不是全部都合適的兵多,比如WebP格式在支持的瀏覽器上加載出來就是WebP,而在不支持他的瀏覽器上加載出來就是JPEG.
<picture>
<source type="image/webp" srcset="images/butterfly.webp">
<img src="images/butterfly.jpg" alt="a butterfly">
</picture>
譯者注:
[1] WebP:這是谷歌定義的一種新的文件格式橄仆,目前還未得到大范圍推廣剩膘,chrome和opera支持,與之一起的還有webM,互聯(lián)網(wǎng)專用的視頻格式
[2] sizes="(max-width: 30em) 100vw 這里的VW單位意思是“viewport width”盆顾,前面的數(shù)字代表的是一個百分比怠褐,100vw的意思是“對象寬度占視圖寬度的100%”,是一個寬度單位您宪。
[3] calc()方法.calc 是 calculate 計算的簡寫奈懒,這個方法允許以表達式的方式來定義樣式,比如calc(100% - 30px)意思就是寬度是比100%視圖寬度窄30px宪巨。MDN提示這是一個實驗性質(zhì)的方法磷杏。