為什么要使用響應(yīng)式圖片戚长?
當(dāng)前整個(gè)前端都有向移動(dòng)端轉(zhuǎn)移的趨勢(shì)盗冷,微信上的各種H5頁(yè)面更是用得飛起,為了吸引用戶同廉,不可避免要用到各種圖片仪糖。圖片的使用面對(duì)兩個(gè)問(wèn)題:
- 該用什么大小的圖片?(不要告訴我手機(jī)上看橫條狀圖片的用戶體驗(yàn)很好)
- 該用什么質(zhì)量的圖片迫肖?(低質(zhì)量圖Retina會(huì)生氣的好嗎)
為什么要寫這篇文章锅劝?
在百度上找,有且僅有一篇淘寶UED寫的CSS與HTML5響應(yīng)式圖片蟆湖,作于2013.1故爵,對(duì)于2014.9才在chrome38+上實(shí)現(xiàn)的響應(yīng)式圖片,幾乎已經(jīng)沒(méi)有實(shí)際價(jià)值隅津。而偶然之間發(fā)現(xiàn)的這個(gè)好玩好用的東西诬垂,因?yàn)橹形馁Y料的稀缺而被湮沒(méi)實(shí)在是可惜。這就是為什么要寫這篇文章的原因伦仍。
掀開(kāi)響應(yīng)式圖片的裙擺
引文中提到的兩個(gè)問(wèn)題能在響應(yīng)式圖片技術(shù)的應(yīng)用中得到較完美的解決结窘。那么問(wèn)題來(lái)了——
什么叫響應(yīng)式圖片?
- 官方范兒的:用戶代理根據(jù)輸出設(shè)備的分辨率不同加載不同類型的圖片充蓝,不會(huì)造成帶寬的浪費(fèi)隧枫。同時(shí),在改變輸出設(shè)備類型或分辨率時(shí),能及時(shí)加載對(duì)應(yīng)類型的圖片悠垛。
- 通俗易懂的:手機(jī)端咱不給它長(zhǎng)條圖线定,給它方塊兒圖;分辨率高的Retina屏幕确买,咱給它@3x圖斤讥,分辨率低的爪機(jī),咱給它質(zhì)量差一點(diǎn)兒的(反正都顯示不出高質(zhì)量的嘛)湾趾。
這貨既然這么好用芭商,這貨怎么來(lái)的?
響應(yīng)式圖片最早起源于W3C上的一個(gè)討論響應(yīng)式圖片的小組搀缠,
跟隨響應(yīng)式網(wǎng)頁(yè)出現(xiàn)铛楣,2014年9月chrome38上正式加入
響應(yīng)式圖片相關(guān)屬性。
兼容性:目前只兼容chrome38+艺普,但是目測(cè)會(huì)普及簸州,因?yàn)樘糜们矣杏昧恕?/strong>
對(duì)付傲嬌的Retina和視流量如生命的移動(dòng)端
首先說(shuō)兩個(gè)我自己遇到過(guò)的問(wèn)題吧。
一是自從用了聯(lián)通4G歧譬,上網(wǎng)爽是爽了岸浑,每個(gè)月交網(wǎng)費(fèi)真是交到哭。最開(kāi)始老懷疑聯(lián)通計(jì)流量的機(jī)制是不是有問(wèn)題瑰步,后來(lái)偶然打開(kāi)一個(gè)微信H5頁(yè)面矢洲,圖多到讓人淚流滿面啊,4G網(wǎng)速快根本看不出來(lái)加載延遲啊缩焦,這么多圖流量跑得飛起啊读虏,知乎回答提示多圖真是良心啊...跑遠(yuǎn)了≡模總之盖桥,桌面端和移動(dòng)端真沒(méi)必要用一樣的圖,給個(gè)30003000的@3x圖放手機(jī)上和700700的@1x有什么區(qū)別呻拌?
二是在做BIOMOD國(guó)際分子生物競(jìng)賽網(wǎng)站的時(shí)候葱轩,首頁(yè)需要放一張超大的gif動(dòng)圖,大家可以感受一下(爪機(jī)流量慎入)藐握。也就是做這個(gè)網(wǎng)站的時(shí)候靴拱,發(fā)現(xiàn)了有響應(yīng)式圖片的存在。
干貨來(lái)了:如何實(shí)現(xiàn)針對(duì)不同設(shè)備自動(dòng)匹配不同質(zhì)量的圖片猾普?
首先袜炕,要匹配不同質(zhì)量的圖片,至少得提供給瀏覽器一堆不同質(zhì)量的圖片吧初家?(不然為啥射雞師苦逼呢...)直接上代碼:
<img
srcset="img/large.jpg 1920w,
img/medium.jpg 960w,
img/small.jpg 310w"
src="img/small.jpg"
alt=“balabbala"/>
這是一個(gè)胖子img標(biāo)簽偎窘,里面多了一個(gè)不熟悉的東西:srcset乌助,里面放了3張圖片,large陌知,medium他托,和small。值得關(guān)注的有兩點(diǎn):
- srcset中的圖片后面跟了個(gè)小尾巴:1920w仆葡,代表width: 1920px赏参。
- 有了srcset,還是需要src鎮(zhèn)場(chǎng)子沿盅,因?yàn)椴皇撬械臑g覽器都叫g(shù)oogle chrome...
對(duì)于胖子img標(biāo)簽把篓,瀏覽器會(huì)自動(dòng)選擇加載最合適的圖片。(最合適腰涧?什么鬼韧掩?但是真的是瀏覽器選的好嗎?窖铡!看看 Eric Portis 帥哥的加載測(cè)試圖表就知道了呢疗锐。瀏覽器的心猜不透啊)
其次万伤,預(yù)期出現(xiàn)medium大兄匣凇(960px)的圖片,結(jié)果出現(xiàn)了large大械新颉(1920px)的圖片,文檔流可能被破壞掉阶界,因此虹钮,重調(diào)大小很重要。sizes屬性派上了用場(chǎng):
sizes="500px"
同時(shí)允許使用媒體查詢的方法控制圖片輸出大斜烊凇:
sizes="(min-width: 41.25em) 38.75em,
calc(100vw - 2.5em)"
因此芙粱,自適應(yīng)輸出質(zhì)量,就是使用srcset給不同質(zhì)量圖片+sizes縮放圖片便于輸出氧映,整體代碼如下:
<img
srcset="img/large.jpg 1920w,
img/medium.jpg 960w,
img/small.jpg 310w"
src="img/medium.jpg"
sizes="(min-width: 41.25em) 38.75em,
calc(100vw - 2.5em)"
alt=“balabbala"/>
消除爪機(jī)上長(zhǎng)條便狀圖片
手機(jī)上的橫條便狀圖片看起來(lái)很不爽春畔,豎屏上的橫條狀圖片并沒(méi)有發(fā)揮移動(dòng)設(shè)備高度遠(yuǎn)大于寬度的特性,用通俗的話說(shuō)岛都,就是丑律姨。
考慮針對(duì)手機(jī)端輸出方塊狀圖片,首先想到的是至少要一張方塊圖和一張長(zhǎng)條圖(用在桌面端)臼疫,再進(jìn)一步想择份,為了發(fā)揮前一部分提及的自適應(yīng)輸出圖片質(zhì)量的方法,我們需要的不是兩張圖片烫堤,而是兩個(gè)srcset荣赶。
問(wèn)題來(lái)了:
- 怎么判斷是爪機(jī)/平板凤价?
- 難道直接在胖子img中塞兩個(gè)src進(jìn)去嗎?
解決第一個(gè)問(wèn)題的思路比較直接拔创,需要用到『響應(yīng)式圖片』的親兄弟:『響應(yīng)式網(wǎng)頁(yè)』中的方法——沒(méi)錯(cuò)利诺,媒體查詢。
這個(gè)時(shí)候我們蛋疼了:媒體查詢media屬性是在標(biāo)簽里寫的剩燥,要是一個(gè)胖子img里面塞兩個(gè)srcset慢逾,media根本沒(méi)法兒寫。
貼心的響應(yīng)式圖片社區(qū)里面的一群大佬開(kāi)始商量:圖片也是一種網(wǎng)頁(yè)上的信息源吧躏吊,直接用source標(biāo)簽裝media屬性+srcset得了氛改。img標(biāo)簽沒(méi)有結(jié)束標(biāo)簽吧?塞不下source標(biāo)簽氨确胜卤!解決方法看起來(lái)笨笨的但是無(wú)力反駁啊:source跟img并列赁项,用個(gè)標(biāo)簽picture包起來(lái)葛躏。代碼:
<picture>
<!-- 16:9 crop -->
<source
media="(min-width: 36em)"
srcset="quilt_2/detail/large.jpg 1920w,
quilt_2/detail/medium.jpg 960w,
quilt_2/detail/small.jpg 480w" />
<!-- square crop -->
<source
srcset="quilt_2/square/large.jpg 822w,
quilt_2/square/medium.jpg 640w,
quilt_2/square/small.jpg 320w" />
<img
src="quilt_2/detail/medium.jpg"
alt="balabalabalaba" />
</picture>
代碼很簡(jiǎn)單:16:9的寬屏圖片用在桌面端,方形的圖片用在移動(dòng)端悠菜。source標(biāo)簽實(shí)現(xiàn)媒體查詢和用來(lái)裝srcset舰攒,這個(gè)時(shí)候胖子img終于成功瘦身,變成古老而苗條的img標(biāo)簽悔醋。最后將source和img用一個(gè)picture標(biāo)簽包起來(lái)就行摩窃。
前瞻性和實(shí)用性的工作
當(dāng)前互聯(lián)網(wǎng)使用最多的圖片格式不外乎:jpg,gif芬骄,png猾愿;最多再加上可以實(shí)現(xiàn)線條運(yùn)動(dòng)和不失真縮放的svg。但 WebP 和 JPEG XR 格式的圖片正在進(jìn)入前端工程師的視野:它們有望實(shí)現(xiàn)超壓縮账阻,并具有無(wú)失真蒂秘、提供alpha通道的特性。[參考自Eric Portis 帥哥的responsive images in practice]
source標(biāo)簽允許加入其他格式的圖片srcset淘太,只需要在標(biāo)簽的type屬性做出相應(yīng)申明即可:
<picture>
<!-- 16:9 crop -->
<source
type="image/webp"
media="(min-width: 36em)"
srcset="quilt_2/detail/large.webp 1920w,
quilt_2/detail/medium.webp 960w,
quilt_2/detail/small.webp 480w" />
<source
media="(min-width: 36em)"
srcset="quilt_2/detail/large.jpg 1920w,
quilt_2/detail/medium.jpg 960w,
quilt_2/detail/small.jpg 480w" />
<!-- square crop -->
<source
type="image/webp"
srcset="quilt_2/square/large.webp 822w,
quilt_2/square/medium.webp 640w,
quilt_2/square/small.webp 320w" />
<source
srcset="quilt_2/square/large.jpg 822w,
quilt_2/square/medium.jpg 640w,
quilt_2/square/small.jpg 320w" />
<img
src="quilt_2/detail/medium.jpg"
alt="balabalabalaba" />
</picture>
看到這兒大概是個(gè)人都得暈姻僧。寫張圖片的代碼量也太坑爹了。
別急蒲牧。本節(jié)標(biāo)題是前瞻性和實(shí)用性撇贺。這不還有一半沒(méi)說(shuō)呢:機(jī)(懶)智(惰)的程序猿給做了代碼生成器。
最后造成,希望大家用的爽显熏!
[引用1:使用了淘寶UEDCSS與HTML5響應(yīng)式圖片中對(duì)響應(yīng)式圖片的中文定義]
[引用2:翻譯并使用了Eric Portis 帥哥的responsive images in practice中對(duì)webP圖片格式的講解及部分源代碼]
作者署名:Hongyang Wang
版權(quán)聲明:自由轉(zhuǎn)載-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
更多內(nèi)容請(qǐng)關(guān)注我的博客:hongyang.space
和我的簡(jiǎn)書(shū)帳號(hào):HongyangWang