記述構文

このモジュールでは、ブラウザが適切な画像を表示できるように、画像を選択できるようにする方法について学習します。srcset 特定のブレークポイントで画像ソースを入れ替えるメソッドではなく、画像ソースを別の画像に入れ替えるものではありません。これらの構文を使用すると、 ユーザーのブラウジング コンテキストに合わせて画像ソースをシームレスにリクエストしてレンダリングするという非常に難しい問題を解決しました。 ビューポートのサイズ、表示密度、ユーザー設定、帯域幅など、数え切れないほどの要素が考慮されています。

これは大きな要望です。ウェブ用の画像をマークアップするだけなので、もっと多くの作業をこなす必要があります。 得られません。

x で記述密度

固定幅の <img> は、ユーザーの密度に関係なく、どのブラウジング コンテキストでもビューポートと同じ大きさを占有します display - 画面を構成する物理ピクセルの数。たとえば、固有の幅が 400px の画像は、その画像のほとんどのスペースを占有します。 初代の Google Pixel と新しい Google Pixel 6 Pro のブラウザ ビューポート全体(どちらのデバイスも 412px は正規化されています) 論理ピクセルのワイドなビューポート。

ただし、Google Pixel 6 Pro ははるかにシャープなディスプレイを備えています。物理解像度は 1, 440 × 3, 120 ピクセルですが、 Pixel は 1,080 × 1,920 ピクセル、つまり画面自体を構成するハードウェア ピクセルの数です。

デバイスの論理ピクセルと物理ピクセルの比率は、そのディスプレイ(DPR)のデバイス ピクセル比です。DPR は デバイスの実際の画面解像度をビューポートの CSS ピクセルで割って計算されます。

コンソール ウィンドウに 2 の DPR が表示されている。

つまり、初代の Google Pixel の DPR は 2.6、Google Pixel 6 Pro の DPR は 3.5 です。

iPhone 4 は、DPR が 1 より大きい最初のデバイスであり、デバイスピクセル比 2 を報告します。 論理解像度が 2 倍になります。iPhone 4 より前のデバイスでは、DPR は 1(1 論理ピクセル対 1 物理ピクセル)の 1 でした。

DPR が 2 のディスプレイで 400px 全体の画像を表示すると、各論理ピクセルは 4 つの画素にわたってレンダリングされます。 水平 2 つと垂直 2 つの物理ピクセルがあります。高密度ディスプレイを使用するメリットはなく、 これは、DPR が 1 のディスプレイの場合と同じです。もちろん、「描画」したものはテキスト、CSS シェイプ、SVG などの要素が、 高密度ディスプレイに合わせて描画されます。しかし、画像形式と圧縮で説明したように、ラスター画像は 使用できます。一見一様ではありませんが、高密度ディスプレイに合わせて拡大されたラスター画像は、 周囲のページと比較すると低解像度です。

このアップスケーリングを回避するには、レンダリングされる画像の固有の幅が 800 ピクセル以上にする必要があります。スケールダウン時 幅 400 論理ピクセルのレイアウトのスペースに収まるようにするため、この 800 ピクセルの画像ソースはピクセル密度が 2 倍になります(DPR が 2 のディスプレイの場合)。 きれいにシャープになります。

密度のばらつきを示す花びらの拡大画像。

DPR が 1 のディスプレイでは高密度な画像を利用できないため、解像度に合わせてダウン ご存知のとおり、縮小された画像でも問題ありません。低密度ディスプレイでは、高密度ディスプレイに適した画像 他の低密度画像と同様に表示されます。

画像とパフォーマンスで説明したように、低密度ディスプレイのユーザーが画像ソースを 400px に縮小して表示しています。 固有の幅が 400px のソースのみが必要です。はるかに大きな画像はすべてのユーザーにとって視覚的に効果的ですが、 高解像度の画像ソースを小型、低密度ディスプレイでレンダリングすると、他の小さい低密度画像と同じように見えますが、非常に遅くなります。

ご想像のとおり、DPR が 1 のモバイル デバイスはごくまれです。 「パソコン」では今でも一般的ですが、ブラウジングのコンテキスト。データに基づく Matt Hobbs が共有しています。2022 年 11 月の GOV.UK ブラウジング セッションの約 18% で、DPR が 1 であると報告されています。高密度画像はユーザーの期待どおりの見た目になりますが、帯域幅と処理コストが大幅に高くなります。 古くてパワフルでないデバイスを使用しているユーザーにとっては、ディスプレイの密度が低い傾向にあります。

srcset を使用すると、高解像度ディスプレイを備えたデバイスのみが、鮮明に表示される十分な大きさの画像ソースを受信し、同じ画像ソースを渡すことはなくなります。 低解像度のディスプレイを使用するユーザーへの 帯域幅コストの増大も予想されます

srcset 属性は、画像をレンダリングするための 1 つ以上のカンマ区切りの候補を指定します。各候補者は 1 つは src で使用するような URL で、もう 1 つはその画像ソースを記述する構文です。srcsetの各候補者 は、その本来の幅(「w 構文」)または目的の密度(「x 構文」)によって記述されます。

x 構文は「このソースは、この密度のディスプレイに適しています」の省略形です。候補の後に 2x が続くと、 DPR が 2 のディスプレイに適しています

<img src="low-density.jpg" srcset="double-density.jpg 2x" alt="...">

srcset をサポートするブラウザには、double-density.jpg の 2 つの候補が表示されます。2x では、この候補が適宜説明されています。 DPR が 2 で、src 属性が low-density.jpg のディスプレイの場合(他に適切なものがない場合に選択された候補) srcset で見つかりました。srcset をサポートしていないブラウザでは、属性とその内容が無視されます(src の内容)。 通常どおりリクエストされます。

srcset 属性に指定された値は、手順と間違われがちです。この 2x は、ブラウザに対して 関連付けられたソースファイルは、DPR が 2(ソース自体に関する情報)のディスプレイで使用するのに適しています。わからない ブラウザにソースの使用方法を伝えるだけで、ソースの使用方法をブラウザに伝えることができます。微妙ながら重要な違いです。 倍密度画像であり、倍密度ディスプレイに使用する画像ではありません。

「このソースは 2x ディスプレイに適しています」という構文の違い「このソースを 2x ディスプレイで使用」というメッセージが表示されています。 印刷媒体ではわずかですが、表示密度は、ブラウザが候補を決定するために使用する膨大な数の相互作用する要因の 1 つにすぎません その一部しか把握できません。たとえば、ユーザーが個別に有効にした prefers-reduced-data メディアクエリを使用して帯域幅を節約できるブラウザ設定を使用し、それを使用して常に低密度の画像を表示するようにします。 表示間隔は問いませんが、すべてのデベロッパー、すべてのウェブサイトで一貫して実装されない限り、ユーザーにとってあまり役に立ちません。 あるサイトでは自分の好みが尊重され、次のサイトで画像の限界に遭遇することもあるでしょう。

srcset/sizes で使用されている、意図的にあいまいなリソース選択アルゴリズムを使用しているため、ブラウザが低密度を選択する余地を残しています。 帯域幅のディップがある画像、またはデータ使用量を最小限に抑えるという優先事項に基づいて作成された画像に対して、Google がその方法、タイミング、タイミングについて 判断できますブラウザがそれに対処できるように、その責務や追加の作業を担うことに意味はありません。

w で幅を記述する

srcset は、画像ソース候補の 2 番目のタイプの記述子を受け入れます。その方がはるかに強力です。Google の目的上、 理解しやすくなっています。特定の表示密度に適した寸法を持つ候補にフラグを立てるのではなく、 w 構文は、各候補ソースに固有の幅を記述します。この場合も、ディメンションを除き、各候補は同じです。 コンテンツ、切り抜き、アスペクト比が同じです。しかし、この場合はユーザーのブラウザが次の 2 つの候補のいずれかを選択します。 600 ピクセルの幅を持つソースの small.jpg と、1,200 ピクセルの幅を持つソースの large.jpg などです。

srcset="small.jpg 600w, large.jpg 1200w"

これは、ブラウザに対してこの情報の処理方法を指示するものではありません。画像の表示候補のリストを提供するだけです。 ブラウザがレンダリングするソースを決定できるように、もう少し詳しい情報を提供する必要があります。 画像がページ上でどのようにレンダリングされるかの説明。そのためには、sizes 属性を使用します。

sizes で使用状況を説明する

ブラウザは、画像転送において非常に高性能です。画像アセットのリクエストは長時間かかります スタイルや JavaScript のリクエストの前に発生することが少なくありません。多くの場合、マークアップが完全に解析される前です。ブラウザが リクエストを実行します。マークアップ以外にページ自体に関する情報はありません。リクエストを開始していない可能性もあります。 適用はもちろん、外部スタイルシートに対するこの時点で、ブラウザはマークアップを解析し、外部 ユーザーのビューポートのサイズ、ユーザーのディスプレイのピクセル密度、 ユーザー設定などが含まれます。

これは、ページ レイアウトでの画像がどのようにレンダリングされるかについて何も示していません。ビューポートを使用することもありません。 img サイズの上限のプロキシとして使用します。これは、水平方向にスクロールするコンテナを占有する場合があるためです。そのために、 その情報をブラウザに提供し、マークアップを使用してそれを行います。このリクエストに使用できるのは、これだけです。

srcset と同様に、sizes はマークアップが解析されるとすぐに画像に関する情報を利用できるようにすることを目的としています。srcset と同様 属性は「ソースファイルとその固有のサイズ」の省略形です。sizes 属性は、「here」の省略形です。 レイアウト内でレンダリングされる画像のサイズです。"画像の説明はビューポートを基準とします 画像のリクエストが行われたときにブラウザが保持する唯一のレイアウト情報は、size のみです。

これは印刷媒体では少し複雑に聞こえるかもしれませんが、実践するとはるかに理解しやすくなります。

<img
 sizes="80vw"
 srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
 src="fallback.jpg"
 alt="...">

ここでは、この sizes 値により、レイアウト内で img が占めるスペースの幅が 80vw(全体の 80%)であることをブラウザに通知しています。 作成します。これは指示ではなく、ページ レイアウトにおける画像のサイズの説明であることに注意してください。「これを書いて」とは書かれていない 画像がビューポートの 80% を占めている場合、「ページがレンダリングされると、この画像がビューポートの 80% を占めることになります。」

デベロッパーの仕事はこれで完了です。srcset でソース候補のリストと画像の幅を正確に記述できました sizes があり、xsrcset 構文と同様に、残りはブラウザが決定します。

しかし、この情報がどのように使用されるかを十分に理解するため、Google Cloud でのデータの取り扱いに関する ユーザーのブラウザがこのマークアップに遭遇すると、次の処理が行われます。

この画像が利用可能なビューポートの 80% を占めることをブラウザに通知しました。そのため、この img を デバイスの場合、この画像は 800 ピクセルを占有します。ブラウザはこの値を受け取り、 srcset で指定した各画像ソース候補の幅。最小のソースは 600 ピクセルのサイズです。 つまり、600÷800=.75 となります。ミディアムの画像は幅 1200 ピクセル、1200÷800=1.5 です。私たちの最大の画像は、幅 2000 ピクセル、2000÷800=2.5 です。

これらの計算結果(.751.52.5)は、実質的にユーザーの状況に応じてカスタマイズされた DPR オプションです。 ビューポートのサイズ。ブラウザには、ユーザーの表示密度に関する情報も保持されているため、次のような一連の処理が行われます。

このビューポート サイズでは、ユーザーの表示密度に関係なく small.jpg の候補が破棄され、計算された DPR がより小さくなります 1 よりも高い場合、このソースはあらゆるユーザーに対してアップスケーリングが必要になるため、適切ではありません。DPR が 1 のデバイスでは、medium.jpg により、 最も近い一致。このソースは DPR が 1.5 での表示に適しているため、必要より少し大きくなります。ただし、ダウンスケーリングは 視覚的にシームレスなプロセスを 実現できますDPR が 2 のデバイスでは、最も近いものとして large.jpg が選択されます。

同じ画像を 600 ピクセル幅のビューポートでレンダリングすると、計算の結果はまったく異なって、80vw は 480 ピクセルになりました。 ソースを分割するとそれに対して 1.252.54.1666666667 を取得します。このビューポートのサイズでは、small.jpg が選択されます medium.jpg は 1x デバイスで一致します。

この画像は、どのブラウジング環境でも同じように見えます。ソースファイルはすべて、サイズ以外はまったく同じです。 ユーザーの表示密度で許容される程度のシャープでレンダリングされている。ただし、すべてのユーザーに large.jpg を提供するのではなく、 最大のビューポートと最も密度の高いディスプレイに対応するために、ユーザーには、常に最適な最小候補が表示されます。 規範的な構文ではなく記述的な構文を使用することで、ブレークポイントを手動で設定する必要がなくなります。また、将来のビューポートや DPR—つまり、ブラウザに情報を与えるだけで、ブラウザが答えを導き出すことができます。

sizes の値はビューポートに関連し、ページ レイアウトから完全に独立しているため、ウォッチフェイスの追加機能のレイヤを追加します。 固定幅の余白、パディング、影響がなく、ビューポートの割合のみを占める画像を使用することはめったにありません ページ上の他の要素と区別できます多くの場合、画像の幅は単位を組み合わせて表現する必要があります。割合、empx など。

幸いなことに、ここでは calc() を使用できます。レスポンシブ画像をネイティブにサポートしているブラウザでは、calc() もサポートされるため、 CSS 単位の組み合わせ(例: ユーザーのビューポートの全幅を占め、左右の余白から 1em を引いた画像)。

<img
    sizes="calc(100vw-2em)"
    srcset="small.jpg 400w, medium.jpg 800w, large.jpg 1600w, x-large.jpg 2400w"
    src="fallback.jpg"
    alt="...">

ブレークポイントの説明

レスポンシブ レイアウトにかなりの時間を費やしてきたなら、以下の例に欠けているものがあることにお気づきでしょう。 レイアウト内で画像が占有するスペースは、レイアウトのブレークポイントを超えて変化する可能性が非常に高いといえます。その場合は、 を使用して、ブラウザにさらに詳しい情報を渡します。sizes は、レンダリングされたサイズの候補のカンマ区切りのセットを受け入れます。 srcset と同様に、画像ソースとしてカンマ区切りで候補を指定できます。これらの条件では、使い慣れたメディアクエリ構文が使用されます。 この構文は最初に一致します。メディア条件が一致するとすぐに、ブラウザは sizes 属性の解析を停止し、 適用されます。

1,200 ピクセルを超えるビューポートで、ビューポートの 80% を占め、左右のパディング em を 1 つ引いた画像があるとします。 小さいビューポートの場合は、ビューポートの全幅を占有します。

  <img
     sizes="(min-width: 1200px) calc(80vw - 2em), 100vw"
     srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     src="fallback.jpg"
     alt="...">

ユーザーのビューポートが 1, 200 ピクセルより大きい場合、calc(80vw - 2em) はレイアウト内の画像の幅を示します。もし (min-width: 1200px) 条件が一致しない場合、ブラウザは次の値に進みます。なぜなら、 メディア条件がこの値に関連付けられている場合は、100vw がデフォルトで使用されます。「kubectl」を使用してこの sizes 属性を記述する場合は、 max-width メディアクエリ:

  <img
     sizes="(max-width: 1200px) 100vw, calc(80vw - 2em)"
     srcset="small.jpg 600w, medium.jpg 1200w, large.jpg 2000w"
     src="fallback.jpg"
     alt="...">

わかりやすい言葉で: 「(max-width: 1200px) は一致するか」そうでない場合は、次に進みます。次の値 calc(80vw - 2em) には修飾条件がありません。 こちらが選択されました

これで、img 要素に関するすべての情報(潜在的なソース、固有の幅、 ブラウザは、あいまいなルールを使用して、画像の処理方法を決定します。 できます。あいまいに思われるかもしれませんが、それは設計上そのとおりだからです。ソース選択アルゴリズムは、 HTML 仕様では、ソースをどのように選択すればよいかが明確にあいまいです。ソース、その記述子、どのように 画像はすべて解析済みです。ブラウザは自由に何でもできます。どの処理が行われるかはわかりません ソースを指定します。

「このソースを高解像度ディスプレイで使用」という構文予測は可能ですが、クラウド コンピューティングで 画像を使用して、ユーザーの帯域幅を節約できます。画面のピクセル密度はインターネットに関係しています 通信速度が遅くなりますトップクラスのノートパソコンを使用し、従量制接続でウェブをブラウジングする場合、テザリングされます。 スマートフォンに接続したり、飛行機の手のひらや Wi-Fi 接続を使用したりするなど、高解像度の画像ソースは、 表示の画質が向上します。

ブラウザに最終的な判断を委ねることで、厳格な規範で管理できる以上のパフォーマンス改善を実現できます。 説明します。たとえば、ほとんどのブラウザでは、srcset または sizes 構文を使用する img は、より小さなソースのリクエストに煩わされることはありません。 ユーザーがブラウザのキャッシュにすでに持っているディメンションよりもソースに対して新しいリクエストを行う目的は何ですか。 ブラウザが既存の画像ソースをシームレスにスケールダウンできるとしたら、同じように見えるでしょうか。しかし、ユーザーが規模を拡大して アップスケーリングを回避するために新しい画像が必要になる時点までビューポートに到達すると、そのリクエストは引き続き行われます。そのため、 確認します

明示的な制御がないことは、額面では少し恐怖に思えるかもしれませんが、使用するソースファイルと同一のものを使用しているため、 「壊れた」コンテンツが表示されなくなると、単一ソースの src よりも優れたエクスペリエンスが ブラウザによる決定を表します。

sizessrcset の使用

これは、読者にとっても、ブラウザにとっても、多くの情報です。srcsetsizes はどちらも密構文です。 驚くべき量の情報を比較的少ない文字数で記述しています。これは、良くも悪くも、 このような構文は簡潔でなく、人間がより簡単に解析できるものであった場合、ブラウザが構文を解析するのが難しくなる可能性があります。「 文字列が複雑になるほど、パーサーのエラーや意図しない動作の違いが生じる可能性が高くなります。 ブラウザ間で移動できます。ただし、これには利点があります。マシンが簡単に読み取れる構文ほど、記述しやすくなる構文です。 できます。

srcset は、自動化に適した明確なケースです。1 対 1 の会議用に複数のバージョンの画像を 代わりに、Gulp などのタスクランナー、Webpack などのバンドラ、サードパーティの Cloudinary などの CDN、または任意の CMS にすでに組み込まれている機能。情報源を生成するのに十分な情報が提供された そもそも、システムには実行可能な srcset 属性に書き込むのに十分な情報があります。

sizes は自動化が少し複雑です。ご存じのように、システムが画像サイズを計算できる唯一の方法は、 レンダリングされるレイアウトのことです。幸いなことに、抽象化機能を提供するさまざまなデベロッパー ツールが 手動では照合できない効率で、sizes 属性を手書きします。 たとえば、respImageLint は、sizes 属性を調査するためのコード スニペットです。 改善案を提供できますLazysizes プロジェクトの侵害 ある程度の効率を上げるため、レイアウトが確立されるまで画像のリクエストを遅らせて、JavaScript が sizes 値を生成します。React や Vue など、完全にクライアント側のレンダリング フレームワークを使用している場合は、 srcset 属性と sizes 属性を作成、生成するためのソリューションが多数あります。これについては、CMS とフレームワークで詳しく説明します。