指示性語法

<picture> 元素不會自行算繪任何內容,而會做為內部 <img> 元素的決策引擎,指出要算繪的內容。<picture> 會遵循 <audio><video> 元素所設定的前例,也就是包含個別 <source> 元素的包裝函式元素。

<picture>
   <source …>
   <source …>
    <img …>
</picture …>

此外,該內部的 <img> 也針對不支援回應式圖片的舊版瀏覽器提供了可靠的備用模式:如果使用者的瀏覽器無法辨識 <picture> 元素,系統就會忽略該元素。然後也會捨棄 <source> 元素,因為瀏覽器完全無法辨識這些元素,或者沒有 <video><audio> 父項,也無法為這些元素提供有意義的上下文。但任何瀏覽器都能辨識內部的 <img> 元素,而且 src 中指定的來源會正常轉譯。

含有<picture>的「藝術指導」圖片

根據網頁中圖片大小變更圖片的內容或長寬比,通常稱為「藝術導向」回應式圖片。srcsetsizes 經過精心設計,可在使用者的瀏覽器指示下順利替換來源。不過,有時您可能會想要改變各個中斷點的來源,以更有效地醒目顯示內容,就像調整網頁版面配置一樣。 舉例來說,中心聚焦較小範圍的全寬標頭圖片在大型可視區域可能成效良好:

標題寬度圖片:一隻淺紫藍色花朵,周圍環繞著葉子和陡峭,且曾是蜜蜂造訪的這裡。

但當您根據小型可視區域縮小圖片時,可能會失去圖片的核心焦點:

縮小的淺紫藍色花朵頁首寬度圖片。蜜蜂是幾乎可見的。

這些圖片來源的 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 元素與其 mediatype 條件相符,圖片將做為「預設」來源。如果使用 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> 僅支援單一 widthheight 屬性,但省略這些屬性可能會導致使用者體驗明顯不佳。為考量這一點,除了 HTML 規格外,「相對」(但支援進一步支援) 允許在 <source> 元素上使用 heightwidth 屬性。這些工作可以減少版面配置位移,就像在 <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>

如果聽起來有點模糊不清,可能是因為以下一個理由:這些網路標準討論會持續進行,但距離已經定案,您目前還無法使用。

雖然回應式圖片標記承諾日後只能更輕鬆地使用,就跟任何網路技術一樣,但有很多服務、技術和架構都能協助減輕使用手寫標記的負擔。在下一個單元中,我們將探討如何將我們學到的圖片格式、壓縮和回應式圖片全部整合到現代的開發工作流程中。