規範的な構文

<picture> 要素は単独では何もレンダリングしませんが、内部 <img> 要素の決定エンジンとして機能し、レンダリングする対象を指示します。<picture> は、<audio> 要素と <video> 要素(個々の <source> 要素を含むラッパー要素)ですでに設定されている前例に従います。

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

この内部の <img> は、レスポンシブ画像をサポートしていない古いブラウザにも信頼性の高いフォールバック パターンを提供します。<picture> 要素がユーザーのブラウザで認識されない場合、その要素は無視されます。その後、ブラウザは要素をまったく認識しないか、<video> または <audio> の親がないと意味のあるコンテキストを持たないため、<source> 要素も破棄されます。ただし、内部の <img> 要素はどのブラウザでも認識され、src で指定されたソースは想定どおりにレンダリングされます。

<picture> の「アート向け」の画像

ページ上の画像のサイズに基づいて画像のコンテンツやアスペクト比を変更することは、一般的に「アート向け」レスポンシブ画像と呼ばれます。srcsetsizes は、目に見えない形で動作し、ユーザーのブラウザの指示に応じて、ソースをシームレスに入れ替えるように設計されています。 ただし、ページ レイアウトを調整する場合と同様に、ブレークポイント間でソースを変更して、コンテンツをより際立たせる必要がある場合があります。 たとえば、中央に小さなフォーカスがある全幅のヘッダー画像は、大きなビューポートで適切に表示されます。

葉と茎に囲まれてミツバチが訪れる、ペリウィンクルの花のヘッダーの幅の画像。

しかし、小さいビューポートに合わせて縮小すると、画像の中心的なフォーカスが失われることがあります。

縮小されたペリウィンクルの花のヘッダー幅の画像。ミツバチはほとんど見えません。

これらの画像ソースの subject は同じですが、その被写体に視覚的に焦点を合わせるには、ブレークポイント間で画像ソースの比率を変更する必要があります。たとえば、画像の中心を拡大してズームすると、端の細部の一部が切り取られます。

ペリウィンクルの花の拡大切り抜き。

このような「切り抜き」は CSS で行えますが、ユーザーは最終的にその画像を構成するデータをすべてリクエストすることになります。

source 要素には、その source の選択条件を定義する属性があります。メディアクエリを受け入れる media と、メディアタイプ(以前の「MIME タイプ」)を受け入れる type です。ユーザーの現在の閲覧コンテキストに一致するソース順序の最初の <source> が選択され、その sourcesrcset 属性の内容を使用して、そのコンテキストの適切な候補が決定されます。この例では、ユーザーのビューポート サイズに一致する 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>

指定した条件に基づいてソースが選択されると、sourcesrcset 属性は、<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 で候補が 1 つしかないため、内部 <img> に対して pic.webp をリクエスト、転送、レンダリングするように指示します。WebP をサポートしていないブラウザは source を無視し、逆の手順がない場合、<img> は 1992 年以降と同様に src のコンテンツをレンダリングします。もちろん、ここでは 2 つ目の <source> 要素を type="image/jpeg" で指定する必要はありません。JPEG が普遍的にサポートされていることを想定できます。

ユーザーのブラウジング コンテキストに関係なく、これらすべてが 1 回のファイル転送で実現されます。レンダリングできない画像ソースに帯域幅を浪費することはありません。また、これは先進的な考えです。より新しく、より効率的なファイル形式には独自のメディアタイプが付属しています。また、JavaScript もサーバー側の依存関係もなく、<img> の速度をすべて備えた picture により、それらを利用できます。

レスポンシブ画像の未来

ここで説明したすべてのマークアップ パターンは、標準化という点で大きな負担でした。<img> として確立され、ウェブの中心的な機能を変更することは容易なことではなく、これらの変更によって解決する一連の問題は、控えめに言っても広範囲に及んでいました。こうしたマークアップ パターンには、改善の余地がたくさんあるとお考えなのであれば、そのとおりです。これらの標準は当初から、将来のテクノロジーが構築される際のベースラインを提供することを目的としています。

これらのソリューションはすべて、サーバーから最初のペイロードに含まれ、ブラウザが画像ソースをリクエストする時間内に到着するように、必然的にマークアップに依存していました。この制約のため、sizes 属性が扱いにくいことが明らかになりました。

ただし、これらの機能がウェブ プラットフォームに導入されたため、画像リクエストを遅らせるネイティブ メソッドが導入されました。loading="lazy" 属性が指定された <img> 要素は、ページのレイアウトが判明するまでリクエストされません。これは、ユーザーの最初のビューポートの外側にある画像のリクエストを、ページのレンダリング プロセスの後半まで延期して、不要なリクエストを回避するためです。ブラウザはこれらのリクエストが行われるときにページ レイアウトを完全に把握しているため、このような場合に手動で記述する sizes 属性を回避するために、HTML 仕様に追加する形で sizes="auto" 属性が提案されています

また、ページ レイアウトのスタイル設定に関する非常に優れた変更に対応するため、<picture> 要素も追加される予定です。ビューポートの情報はレイアウトについて大まかに決めるうえで健全な基盤ですが、開発において完全なコンポーネント レベルでのアプローチを取ることは不可能です。つまり、ページ レイアウトの任意の部分にドロップできるコンポーネントで、そのコンポーネント自体が占めるスペースに反応するスタイルを持つことは不可能です。この懸念からコンテナクエリが作成されました。これは、ビューポートだけではなく、親コンテナのサイズに基づいて要素のスタイルを設定する方法です。

コンテナのクエリ構文は安定したばかりで(現時点ではブラウザのサポートは非常に限られています)、それを可能にするブラウザ テクノロジーを追加することで、<picture> 要素に同様のことを行えます。これは、ビューポートのサイズに基づくのではなく、<picture> 要素の <img> が占有するスペースに基づいて <source> の選択基準を許可する container 属性です。

少し曖昧に思われるかもしれませんが、それには正当な理由があります。これらのウェブ標準に関する議論は続いていますが、まだ決着のつかない段階にあり、現時点ではまだ使用できません。

レスポンシブ画像マークアップは、他のウェブ テクノロジーと同様に、次第に扱いやすくなると期待されていますが、このマークアップを手書きする負担を軽減するためのサービス、テクノロジー、フレームワークは数多くあります。次のモジュールでは、画像形式、圧縮、レスポンシブ画像について学んだすべてを最新の開発ワークフローに統合する方法について説明します。