使用srcset實現響應式圖片 sizes屬性

來源:互聯網
上載者:User

圖片要在各種裝置上平滑過渡顯示,它們將會碰到的問題有:1.適當的最佳化和減少圖片的體積;2.注意不要浪費頻寬(網站的成敗與否載入速度是其中主要因素之一);3.裝置使用相應的解決方案。


對於第一個問題,使用TinyPng和JPEGmini工具可以協助減少圖片的體積和最佳化圖片。

對於第二個問題,在一些場合下我們可能要使用到強大的媒體查詢。多虧了有他們,我們可以很簡單的處理背景圖片的問題。但是,有些地方使用的是img來顯示圖片,這也是我們要解決的第三個問題,也是最後一個問題,如何根據裝置的解析度調用合適的映像。

在這種情況之下,有個兩個解決方案:使用<picture>元素和<img>元素的srcset屬性。

在這篇文章中,我會向大家總體的介紹srcset屬性。


srcset屬性

使用這個屬性主要有什麼好處呢?好處就是Web開發人員可以給使用高解析度的使用者顯示高分辨的映像源,給其他裝置解析度的使用者使用其他的映像源。在第一種情況下使用低PDD(pixel density displays)不需要背負著下載無用的高解析度映像,而擔心浪費頻寬;而後者可以享受高清裝置帶來的不一樣的享受。在第二種情況中,我們可以根據不同的螢幕尺寸指定不同的映像,這主要是根據使用者的裝置來提供一個較好的映像源。

事實上,srcset屬性就做了這樣的事情,根據像素密度或使用者使用的螢幕尺寸大小,指定一個映像源。所以說,srcset屬性可以讓瀏覽器提供一套"建議",讓瀏覽器根據正確的行為匹配正確的映像。通過這樣做,我們提高了Web的品質,同時提高了Web頁面的載入速度和給使用者一個較好的體驗。

在這一點上,這個屬性的基本特徵就是:根據指定的條件來做選擇,使其工作。這對於我們編碼工作和實現的方法變理更為簡易。

W3C規範是這樣描述srcset:srcset屬性允許作者根據不同解析度或不同的視窗尺寸提多個不同分辨映像。使用者代理程式會根據之前擷取的任何資源做選擇,從而避免多個資源載入浪費頻寬和相關效能問題。

原話:

    The srcset attribute allows authors to provide, in a compact manner, multiple variants of the same image at differing resolutions or for different viewport dimensions. User Agents may make their resource selection before fetching any of the resources, thus avoiding multiple resource loads and the associated performance problems in constrained bandwidth environments.

srcset屬性包含一系列的逗號分隔值,一方面是指定映像的url,另一方面指映像將要顯示的條件。映像條件我們可以看到有像素密度、視窗尺寸大小或者同時兩者都存在。有一點非常有趣,瀏覽器可以根據使用者的設定或頁面訪問時間,選擇或抓取一個低分辨映像和高分辨映像。

想象一下,在你的行動瀏覽器喜好設定允許請求高分辨映像。例如,只有當串連到wifi的網路環境,或者在網路不強時會詢問你是否手動設定瀏覽器偏好,允許載入低分辨映像。

文法格式如下:

<img src="small-photo.jpg" srcset="big-photo.jpg 2x" />

上面的代碼要求瀏覽器顯示名為small-photo.jpg映像。除非在一個高分辨顯示器(像素密度為2x,比如Retina螢幕),才顯示名為big-photo.jpg映像。請注意,只有瀏覽器理解這個屬性才會顯示其他映像,如果瀏覽器不能正確的解釋這個屬性,流星器會忽略其他映像,回退到src屬性指定的映像。

如上所述,這個屬性不僅限於高密度解析度的裝置。在一些情況下,還可以根據螢幕的視窗尺寸的寬度來選擇圖片,這就相當於媒體查詢查到一個斷點時載入背景映像。受益於它,你必須在指定的像素的數量後跟一個w(例如600 w)。為了更好的理解這個樣本,讓我們來看一個來自Sxc.hv網站的效果——"莫斯科的秋季"。壓縮後的尺寸是1368 x 700,最佳化後體積是389kb。

到目前為止,我們所討論的優勢是讓使用者在使用他們的智能手機上網時下載一張大小比裝置更大的映像,那麼他的裝置可以顯示嗎?此外,請記住移動串連受到一定的限制,一個棘手的問題就是映像過大將減緩你的頁面載入,這可能會導致您的使用者離開你的網站(很明顯,首要的就是避免這種現像)。已經說過了,你可以考慮使用和裝置尺寸相同的映像,比如尺寸400 x 22px,大小約40kb。


令人難以置信的是,使用下面的一段代碼,我們就可以讓使用者節省頻寬和改善使用者的體驗:

<img src="low-density-photo.jpg" srcset="small-photo.jpg 480w, big-photo.jpg 1024w, high-density-photo.jpg 1024w 2x" />

這段代碼使用了low-density-photo.jpg映像作為候選映像,根據不同的條例提供了顯示映像的一個列表:裝置螢幕寬度小於或等於480px螢幕使用small-photo.jpg,裝置螢幕寬度小於或等於1024px使用big-photo.jpg,最後是有兩個條件,裝置螢幕小於或等於1024的Retina屏將顯示high-density-photo.jpg映像。

有一個不太好的訊息要告訴你,目前支援srcset的瀏覽器只有Webkit引擎的瀏覽器:



此外,你不能設定一個映像基於max-width裝置的螢幕,因為目前還沒有具體說明如何使用。這個問題有點複雜,所以要不斷檢查規範是否有更新,閱讀更多關於它的規範和方法才能更好的實現你的項目需求。

有關於srcset的W3C規範的草案在2013年12月2日發布了,草案中包含了一些有關於這個屬性使用的樣本和如何使用這個屬性。

作為一個編輯的草案,我們也只能說這個屬性離我更近,至於什麼時候瀏覽器能全面支援和使用srcset屬性,我們只能抱著希望期待。


在本文中,我們已經描述了srcset屬效能更好的協助Web開發人員更好的管理網站的圖片。然而,正如我們所看到的,目前支援的瀏覽器還很少,但我們有自信,瀏覽最終將會解決這個問題。



響應式圖片srcset全新釋義sizes屬性w描述符

說起圖片的srcset屬性,估計有不少與時俱進的小夥伴會在心中不由自主念想道:“這個我知道的,可以根據螢幕密度現實對應尺寸圖片,例如……”

<img src="mm-width-128px.jpg" srcset="mm-width-128px.jpg 1x, mm-width-256px 2x">

上面代碼對應demo輕戳這裡。當然,我們也可以簡寫成:

<img src="mm-width-128px.jpg" srcset="mm-width-256px 2x">

由於我們都不是“別人家”的公司,因此,我們的辦公PC顯示器預設裝置像素比都是1,因此,這些顯示器呈現的圖片預設都是128像素寬度的。下面問題來了,(不是挖掘機哪家強),如何讓?潘肯允酒髂D飧呱璞趕袼乇饒兀?br/>
方法一:
Chrome瀏覽器,切換裝置模式,如下截圖(v38):


然後,選擇對應的裝置,例如iPhone6 Plus的裝置像素比就是3.


此時,重新整理頁面,載入的就是大尺寸圖片,也就是256像素寬度那張。

方法二:
Chrome瀏覽器,Ctrl+✚快速鍵,或者ctrl + 滑鼠滾輪,放大頁面的比例,例如,試試放大到150%:


此時裝置像素比window.devicePixelRatio為1.5,因此載入的就是256像素寬度的圖片。有圖有真相:


不同的2x顯示策略
還有些時候,使用同尺寸的高清圖片作為2x對應圖片,雖然兩者圖片大小差不多,但個人覺得還是2倍尺寸最佳化大圖更好一點,為什麼呢?

srcset當初設計的用意是為了高密度螢幕上圖片更好的顯示,如果世界上就只有“不同裝置密度”這一個戲劇衝突的話,2x圖片是高清圖還是2倍尺寸圖其實都無傷大雅。然而,事實上,生活無處不戲劇,現代web布局中,有種布局不可忽略,那就是「響應式布局」,劇本往往會這樣,PC瀏覽器上顯示大圖,Mobile瀏覽器上顯示小圖。發現沒,同樣是“大小圖的要求”,和裝置像素比有類似的戲劇衝突。

於是,如果我們2x圖片使用的是高清圖,結合響應式布局,我們可能需要4張圖片資源,即:小圖、小圖高清和大圖、大圖高清。但是,2x圖片走的是2倍尺寸圖片,我們只需要3張圖片資源,即:小圖、中圖以及中圖、大圖。

在老一代srcset規範成型過程中,其實已經考慮到與響應式布局的糾葛,出現了w描述符,例如,走高清路線的:

<img src="small.jpg" srcset="small.jpg 640w 1x, small-hd.jpg 640w 2x, large.jpg 1x, large-hd.jpg 2x">

走2倍尺寸路線的:

<img src="small.jpg" srcset="small.jpg 640w 1x, medium.jpg 640w 2x, medium.jpg 1x, large.jpg 2x">

注意啊注意:千萬不要去關心上面的w描述符的含義,因為新的srcset屬性中w描述符含義與之完全不同,為了避免理解衝突,心中跟我默念3遍:忘掉它、忘掉它、忘掉它,無視它、無視它、無視它。大家可以把精力放在下面,新的srcset規範以及新的sizes屬性文法含義等。


恰如其分的時間點

我們去caniuse上查看srcset屬性的瀏覽器支援情況,會發現有黃黃綠綠的顏色:


可以看到,Chrome瀏覽器下,從版本38開始是綠色的,而之前是黃綠色。黃綠色表示僅支援舊的srcset規範,綠色表示支援全新的srcset規範,包括sizes屬性,w描述符。

而Chrome 38穩定版就在上周發布(騰訊軟體管家顯示10月16號也就是前幾天發布的),於是,我們就有條件實踐srcset新規範特性,有利於快速學習。

因此,我才選擇在這個時間點寫這篇文章,推產品也是如此,需要一個合適的時間點,太早的死在沙灘上,太晚的落後跟不上。

因此,若要學習本文內容,看看您的Chrome瀏覽器是否是38+.

於此同時,蘋果剛發布了4x的顯示器,如果使用傳統srcset,需要1x, 2x, 3x, 4x, 我勒個去,HTML立馬變成了臃腫的大胖子。與時俱進勢在必行!


全新的智能srcset、sizes屬性, w描述符

舊的srcset是人主導,而現在新的srcset是瀏覽器主導,你主需要提供圖片資源、以及斷點,其他都交給瀏覽器智能解決,什麼響應寬度啊、裝置像素比啊,你都不要關心了,瀏覽器會自動匹配最佳顯示圖片。你的表情現在是不是這樣子啊:
酷斃了 表情

如下HTML樣本:

<img class="image" src="mm-width-128px.jpg"
     srcset="mm-width-128px.jpg 128w, mm-width-256px.jpg 256w, mm-width-512px.jpg 512w"
     sizes="(max-width: 360px) 340px, 128px">

其中1:
srcset用來指向提供的圖片資源,注意,僅僅是資源指向,沒有以前的1x, 2x什麼的,這個都交給瀏覽器了,我們不需要關心!例如這裡,指向了3個尺寸圖片,分別實際尺寸128像素,256像素和512像素。

其中2:
sizes用來表示尺寸臨界點,主要跟響應式布局打交道。文法如下:

sizes="[media query] [length], [media query] [length] ... etc"

例如上述代碼中,size = "(max-width: 360px) 340px, 128px"表示當視區寬度不大於360像素時候,圖片的寬度限制為340像素,其他情況下,使用128像素(對應下面demo頁面第1張圖)。

如果sizes="128px", 則尺寸就一直是128像素,圖片只會根據裝置像素比發生變化。

注意,這裡所有的值都是指寬度值,且單位任意,em, px, cm, vw, ...都是可以的,甚至可以CSS3的calc計算(對應下面demo頁面第2張圖),例如:

sizes="(max-width: 360px) calc(100vw - 20px), 128px"

表示當視區寬度不大於360像素時候,圖片寬度為整個視區寬度減去20像素的大小。

OK,上面2個屬性具體如何起作用的呢?首先,你需要狠狠地點擊這裡:srcset與sizes新釋義w描述符示意demo

1. 裝置像素比的對應顯示
按照Part2的提示,F12點擊切換裝置模式,我們先看下大寬度尺寸下的顯示,例如,我們選擇個iPad 1:


其中fit前面的鉤鉤去掉,以更清晰的顯示。此時,大家可以看到,圖片顯示的是128像素寬度的。為什麼呢?

還記得咱們的sizes屬性值嗎?最後光禿禿沒有媒體查詢的值就是128px, 目前視圖寬度是1024像素,遠遠大於360像素這個臨界寬度值,因此,圖片佔據寬度是128像素。同時,最最重要的是,這裡的裝置像素比是1.
裝置像素比是1

因此,我們可以正兒八經顯示實際寬度是128像素的那張圖了。最終顯示如下:


//zxx: 上下兩張圖上面已經提到過,代碼差異僅僅是sizes的一個臨界寬度值不一樣,上面的是340px,下面的是calc(100vw - 20px),有助於大家深入理解w描述符,後面有大量戲份,當然,這裡,大家可暫時不用關心。

OK,保持寬度不變,我們變一個小魔術,下面,把裝置像素比1改成2然後重新整理頁面:

於是,噹噹噹噹,見證奇蹟的時刻到了,圖片256了:


同樣的,我們修改裝置像素比是3再重新整理頁面,會發現圖片載入的是512寬度那種:


如果改成4+,還是上面這種512像素寬度的圖片,因為這是我們給瀏覽器提供的最大w對應的圖片了。

大家注意到木有,我們完全沒有指定瀏覽器那個裝置像素比使用哪個圖片,瀏覽器非常smart幫我們載入了最佳顯示的圖片。這就是最新的srcset的釋義,更智能更強大。

2. sizes的媒體查詢

下面我們深入理解下sizes屬性的作用機制。

首先,我們修改裝置為Google Nexus5, 此時視區寬度為360像素,正好是sizes設定的臨界寬度值,修改裝置像素比為1(去除其他測試幹擾因素),重新整理頁面,會發現頁面載入的是512這張圖:

為什麼載入是512呢?

依次看來,首先第一張圖,對應值是(max-width: 360px) 340px, 意思通俗易懂,視區寬度不大於360像素時候,圖片實際尺寸340像素。此demo兩側各有10像素空白,因此,正好圖片滿屏顯示的感覺。下面問題來了,為什麼載入的是512這種圖,而不是256?

大家還記不記得srcset中每張圖片資源後面的w描述符的值大小?沒錯,分別是128w, 256w, 512w. 正好這裡解釋下w描述符的意思,根據我個人的理解(注意,是個人理解,僅供參考),w用來描述檔案的寬度,我們可以形象理解為規格,就像手機一樣,有大小不一樣的尺寸與規格。根據我淺薄的經驗,我們可以直接等同於像素去理解。可能你會疑問,那為何不直接256px而是256w, 因為,請注意,這裡的256w並不是指圖片的寬度,而是圖片的寬度規格,例如,一張圖片實際寬度是256像素,但是,這種圖片是png24無損圖片,或100%品質JPG圖片,則,我們可以使用512w表示這張圖片,品質好規格就高,不難理解吧!如果是512px顯然就有問題了,明明圖片256像素,搞個512px,歧義到王母娘娘哪兒去了!因此,需要一個沒人見過的w表示,同時,需要意識到,w不是單位,而是一個描述符(descriptor)。

回到主線,圖片340像素,可以看出340規格,340w, 於是256w這張圖片顯示就規格不夠,簡稱“不夠格”;512w > 340w,滿足最優顯示準則,於是,載入的就是512px這張圖。

如果你希望視圖360像素寬度時候載入的是256這張圖片,很簡單,修改其規格256w為340w, done!

OK, 注意注意,前方高能!!

下面,不是下餃子,修改寬度為一個吉利的數字 ? 250, 然後刷一下(注意裝置像素比要為1)~~會發現,上下兩張圖的差異來了,如下截圖:



雖然圖片都是100%父容器顯示,但載入的圖片卻不一樣。咦?為何會不一樣呢?

其實很好理解,前者是340px, 後者是calc(100vw - 20px),一個是定值,一個動態。前者永遠是340w規格,而後者在尺寸是250像素時候,實際像素是230px, 可以看成230w,比256w小,於是就載入了256這種圖片啦!

因此,如果大家希望圖片的載入進一步智能,建議使用動態單位。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.