<picture>
元素不會自行算繪任何內容,而會做為內部 <img>
元素的決策引擎,指出要算繪的內容。<picture>
會遵循 <audio>
和 <video>
元素所設定的前例,也就是包含個別 <source>
元素的包裝函式元素。
<picture>
<source …>
<source …>
<img …>
</picture …>
此外,該內部的 <img>
也針對不支援回應式圖片的舊版瀏覽器提供了可靠的備用模式:如果使用者的瀏覽器無法辨識 <picture>
元素,系統就會忽略該元素。然後也會捨棄 <source>
元素,因為瀏覽器完全無法辨識這些元素,或者沒有 <video>
或 <audio>
父項,也無法為這些元素提供有意義的上下文。但任何瀏覽器都能辨識內部的 <img>
元素,而且 src
中指定的來源會正常轉譯。
含有<picture>
的「藝術指導」圖片
根據網頁中圖片大小變更圖片的內容或長寬比,通常稱為「藝術導向」回應式圖片。srcset
和 sizes
經過精心設計,可在使用者的瀏覽器指示下順利替換來源。不過,有時您可能會想要改變各個中斷點的來源,以更有效地醒目顯示內容,就像調整網頁版面配置一樣。
舉例來說,中心聚焦較小範圍的全寬標頭圖片在大型可視區域可能成效良好:
但當您根據小型可視區域縮小圖片時,可能會失去圖片的核心焦點:
這些圖片來源的 subject 相同,但為了更聚焦於主題的視覺呈現,建議您調整圖片來源的比例,在不同中斷點進行變化。舉例來說,您可以縮小圖片中心的縮放比例,而邊緣的部分細節經過裁切:
這種「裁剪」功能可透過 CSS 完成,但使用者可能會要求所有製作該圖片的資料,即使最後實際看不到也沒關係。
每個 source
元素都具有定義 source
選取條件的屬性:media
(接受媒體查詢) 和 type
(先前稱為「MIME 類型」)。來源順序中的第一個 <source>
符合使用者目前瀏覽情境,則系統會使用該 source
上的 srcset
屬性內容判斷適合該背景資訊的候選文字。在本例中,系統會選取第一個含有 media
屬性與使用者可視區域大小相符的 source
:
<picture>
<source media="(min-width: 1200px)" srcset="wide-crop.jpg">
<img src="close-crop.jpg" alt="…">
</picture>
您應一律按照順序指定內部 img
,如果沒有任何 source
元素與其 media
或 type
條件相符,圖片將做為「預設」來源。如果使用 min-width
媒體查詢,請優先採用最大來源,如上述程式碼所示。使用 max-width
媒體查詢時,應先放置最小的來源。
<picture>
<source media="(max-width: 400px)" srcset="mid-bp.jpg">
<source media="(max-width: 800px)" srcset="high-bp.jpg">
<img src="highest-bp.jpg" alt="…">
</picture>
根據您指定的條件選擇來源時,source
上的 srcset
屬性會連同 <img>
本身的定義一起傳遞至 <img>
。也就是說,您也可以使用 sizes
來最佳化藝術導向圖片來源。
<picture>
<source media="(min-width: 800px)" srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w">
<source srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w">
<img src="fallback.jpg" alt="…" sizes="calc(100vw - 2em)">
</picture>
當然,如果圖片的比例可能因所選 <source>
元素而變化,就會引發效能問題:<img>
僅支援單一 width
和 height
屬性,但省略這些屬性可能會導致使用者體驗明顯不佳。為考量這一點,除了 HTML 規格外,「相對」(但支援進一步支援) 允許在 <source>
元素上使用 height
和 width
屬性。這些工作可以減少版面配置位移,就像在 <img>
上一樣,為已選取的 <source>
元素在版面配置中保留適當空間。
<picture>
<source
media="(min-width: 800px)"
srcset="high-bp-1600.jpg 1600w, high-bp-1000.jpg 1000w"
width="1600"
height="800">
<img src="fallback.jpg"
srcset="lower-bp-1200.jpg 1200w, lower-bp-800.jpg 800w"
sizes="calc(100vw - 2em)"
width="1200"
height="750"
alt="…">
</picture>
請特別注意,圖片方向不僅可用於依據可視區域大小決定的決定,也應該使用 srcset
/sizes
更有效率地處理大多數情況。例如,根據使用者偏好設定選擇更合適的色彩配置的圖片來源:
<picture>
<source media="(prefers-color-scheme: dark)" srcset="hero-dark.jpg">
<img srcset="hero-light.jpg">
</picture>
type
屬性
type
屬性可讓您使用 <picture>
元素的單一要求決策引擎,只向支援圖片格式的瀏覽器提供圖片格式。
如圖片格式和壓縮一文所述,瀏覽器還無法剖析編碼為圖片資料。
在 <picture>
元素推出前,提供新圖片格式最可行的前端解決方案,需要瀏覽器先要求並嘗試剖析圖片檔,才能判斷是否要將其捨棄並載入備用檔案。常見的例子是沿著以下幾行程式碼編寫的指令碼:
<img src="image.webp"
data-fallback="image.jpg"
onerror="this.src=this.getAttribute('data-fallback'); this.onerror=null;"
alt="...">
使用這個模式時,系統仍會在所有瀏覽器中發出 image.webp
要求,也就是因不支援 WebP 的瀏覽器,遭到浪費。無法剖析 WebP 編碼的瀏覽器會擲回 onerror
事件,並將 data-fallback
值切換為 src
。這是一個浪費資源的解決方案,但這同樣的方法也是在前端唯一可用的選項。請記住,瀏覽器在任何自訂指令碼都有機會執行 (甚至可以剖析) 之前,就開始發出圖片要求,因此我們無法先佔這項程序。
<picture>
元素是經過明確設計,可避免這些多餘的要求。雖然瀏覽器在未要求的情況下,仍無法識別不支援的格式,但 type
屬性會預先警告瀏覽器來源編碼,因此可以決定是否要提出要求。
在 type
屬性中,您必須提供每個 <source>
的 srcset
屬性內指定圖片來源的媒體類型 (舊稱 MIME 類型)。如此一來,瀏覽器就能取得所有所需的資訊,立即判斷 source
提供的候選圖片是否可在不提出任何外部要求的情況下解碼。如果媒體類型無法辨識,系統會忽略 <source>
和所有候選項目,並繼續執行瀏覽器。
<picture>
<source type="image/webp" srcset="pic.webp">
<img src="pic.jpg" alt="...">
</picture>
在這裡,任何支援 WebP 編碼的瀏覽器會識別 <source>
元素 type
屬性中指定的 image/webp
媒體類型,然後選取該 <source>
,且因為我們在 srcset
中只提供一個候選項目,藉此指示內部 <img>
來要求、轉移並轉譯 pic.webp
。凡是「不支援」WebP 的瀏覽器都會忽略 source
,且沒有相反的操作說明,<img>
會像 1992 年以來一樣轉譯 src
的內容。當然,您不用在此使用 type="image/jpeg"
指定第二個 <source>
元素,也可以假設 JPEG 通用支援。
無論使用者的瀏覽情境為何,只要傳輸單一檔案就能完成這些操作,對於無法算繪的圖片來源也不會浪費頻寬。這也有前瞻性思維,此外,高效率的檔案格式會自行導入媒體類型,而我們只要使用 picture
就能加以利用,而且沒有 JavaScript、沒有伺服器端依附元件,以及 <img>
的所有速度。
回應式圖片未來趨勢
本文討論的所有標記模式在標準化方面都是一項劇烈的幫助:<img>
改變了已建立且位在網路的核心功能,這不僅是相當大的事,而且想解決的一系列問題絕非易事。如果您自認為這些標記模式還有很多改善空間,那當然是正確的。從一開始,這些標準旨在為未來要建構的技術提供基準。
所有這些解決方案都必須仰賴標記,例如加入來自伺服器的初始酬載,並及時要求瀏覽器要求圖片來源,這只是導致應用程式本身受到的限制 sizes
屬性。
不過,由於這些功能已於網路平台推出,因此導入了延遲圖片要求的原生方法。系統只有在已知網頁版面配置的情況下,才會要求含有 loading="lazy"
屬性的 <img>
元素,以便將使用者初始可視區域外的圖片要求延後,直到系統轉譯網頁程序稍後完成,才可能避免不必要的要求。由於瀏覽器在發出這些要求時完全瞭解網頁版面配置,因此建議將 sizes="auto"
屬性新增為 HTML 規格的附加狀態,避免在這類情況下手動編寫的 sizes
屬性。
此外,我們還新增了水平上的 <picture>
元素,以配合我們對網頁版面配置的樣式設定方式,進行一些令人驚豔的變更。雖然可視區域資訊是高階版面配置決策的音效基礎,但我們無法採用完整的元件層級開發方法,也就是可置入至網頁版面配置的任何部分的元件,而且樣式會回應元件所佔的空間。這個疑慮導致系統建立容器查詢,這是根據父項容器的大小 (而非單獨檢視可視區域) 來設定樣式元素的方法。
雖然容器查詢語法只無法穩定運作,且瀏覽器支援非常有限,但在寫入時,新增的瀏覽器技術將會為 <picture>
元素提供相同的功用:一個潛在的 container
屬性,可讓您根據 <picture>
元素的 <img>
佔用空間 (而非依據可視區域的大小) 選擇 <source>
。
如果聽起來有點模糊不清,可能是因為以下一個理由:這些網路標準討論會持續進行,但距離已經定案,您目前還無法使用。
雖然回應式圖片標記承諾日後只能更輕鬆地使用,就跟任何網路技術一樣,但有很多服務、技術和架構都能協助減輕使用手寫標記的負擔。在下一個單元中,我們將探討如何將我們學到的圖片格式、壓縮和回應式圖片全部整合到現代的開發工作流程中。