srcset にピクセル密度記述子を設定した場合の動作を確認します。
こちらの記事では、srcsetを利用してピクセル密度記述子を利用して解像度が高いディスプレイでの画像表示に対応しました。
通常の画像表示では問題ありませんが、画像のサイズによって微妙に動作が違う場合があります。
この記事では、srcsetでピクセル密度記述子を使用した場合に、記述方法や画像サイズによってどのような違いが出るか動作を確認します。
次の4つの画像を準備します。
img タグにsrc属性のみを記述し、srcsetを記述しない場合の動作です。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset なしの表示</h2>
<img src="image\image-w400.png" /><br />
<img src="image\image-w800.png" /><br />
<img src="image\image-w1800.png" /><br />
<img src="image\image-w3600.png" /><br />
</body>
</html>
特に問題なく表示できています。
縮小した場合の表示です。
画像が引き延ばされて表示されています。オレンジのimage-w400.png
の表示サイズの横幅は800ピクセルあります。
Webブラウザの表示倍率を変更して縮小して表示した画面です。
表示に特に問題はありません。高解像度のディスプレイでは実際の画像の2倍の大きさで表示されています。
imgタグにsrcset属性を記述して表示を確認します。
1x,2x,4x, 8x
を指定した場合と 1x, 2x, 3x, 4x
を指定した場合とで動作の違いが出るかを確認します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset ありの表示</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 4x, image\image-w3600.png 8x" /><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 3x, image\image-w3600.png 4x" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 4x" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 3x" /><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 1x, image\image-w3600.png 2x" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" /><br />
</body>
</html>
すべての画像が一番サイズの大きい image-w3600.png
の画像が利用されていることがわかります。
Webブラウザの表示倍率を変更して縮小した場合の表示です。
画像は一番大きい画像が使われますが、画像の幅は記述したピクセル密度記述子に合わせてリサイズされています。
一番上の画像は image\image-w3600.png 8x
が採用されているため、8分の1のサイズの横幅450ピクセルで表示されており、2番目の画像はimage\image-w3600.png 4x
が採用されているため、
4分の1のサイズでの横幅900ピクセルで表示されています。
srcsetが設定されている場合には一番解像度が高い設定が採用される動作になっているようです。
高解像度設定でも、すべての画像が一番サイズの大きい image-w3600.png
の画像が利用されていることがわかります。
Webブラウザの表示倍率を変更した場合の表示です。
一番上の画像は image\image-w3600.png 8x
が採用されているため、8分の1のサイズの横幅450ピクセルでの表示になりますが、高解像度ディスプレイのため2倍のサイズの横幅900ピクセルで表示されています。また、2番目の画像はimage\image-w3600.png 4x
が採用されているため、4分の1のサイズでの横幅900ピクセルの2倍の表示の1800ピクセルで表示されています。
高解像度ディスプレイでも、srcsetが設定されている場合には一番解像度が高い設定が採用され、横幅はピクセル密度記述子に合わせて表示する動作になっているようです。
imgタグにsrcset属性を記述しますが、大きい解像度の画像に小さい画像を指定した場合にどのような表示になるかを確認します。
<h2>srcset ありの表示 (逆転)</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 8x, image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" /><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 4x, image\image-w800.png 3x, image\image-w1800.png 2x, image\image-w3600.png 1x" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 3x, image\image-w1800.png 2x, image\image-w3600.png 1x" /><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 2x, image\image-w3600.png 1x" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" /><br />
こちらの設定の場合、マシンによって動作が違います。
下図の表示結果となります。一番大きい解像度設定が利用されるため、最初の画像は image\image-w3600.png 1x
が採用されます。1xの設定が反映されるため元の画像サイズで画像が表示されます。
Webブラウザの表示倍率を変更して画面を縮小した場合の表示です。
下図の表示結果となります。一番大きい解像度設定が利用されるため、最初の画像は image\image-w400.png 8x
が採用されます。8xの設定が反映され8分の1のサイズにリサイズされるため、
横幅50ピクセルで画像が表示されます。
2番目の画像はimage\image-w400.png 4x
が採用され、4分の1のサイズにリサイズされ、横幅100ピクセルでの表示になります。
Webブラウザの表示倍率を変更して画面を縮小した場合の表示です。
こちらの設定の場合、マシンによって動作が違います。
通常の解像度のディスプレイと同じ表示になります。
一番大きい解像度設定が利用されるため、最初の画像は image\image-w400.png 8x
が採用されます。8xの設定が反映され8分の1のサイズにリサイズされますが、
高解像度ディスプレイのため、2倍されて、横幅100ピクセルで画像が表示されます。
下図の表示となります。
一番大きい解像度の設定ではなく、image\image-w1800.png 2x
が採用されます。
2xの設定が反映されるため、2分の1のサイズにリサイズされ、高解像度ディスプレイの設定が反映されるため、元の大きさと同じ横幅1800ピクセルで画像が表示されます。
微妙な挙動の違いは、ブラウザの違いによる動作違いが影響している可能性が高そうです。
続いて、imgタグのwidth属性を指定して横幅を固定した場合の表示を確認します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset なしwidth指定(width=600)の表示</h2>
<img src="image\image-w400.png" width="600"/><br />
<img src="image\image-w800.png" width="600" /><br />
<img src="image\image-w1800.png" width="600" /><br />
<img src="image\image-w3600.png" width="600" /><br />
</body>
</html>
下図の表示になります。width=600 が指定されているため、image-w400.png の画像は引き延ばされて表示されます。
高解像度のディスプレイでの表示は下図となります。解像度が2倍の設定のため、表示画像の横幅は1200ピクセルになります。
image-w400.png, image-w800.png の画像は引き延ばされた表示になります。
imgタグのwidth属性を指定して横幅を固定し、srcset属性を設定した場合の表示を確認します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset あり width指定(width=600)の表示</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 4x, image\image-w3600.png 8x" width="600"/><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 3x, image\image-w3600.png 4x" width="600" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 4x" width="600" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 3x" width="600"/><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 1x, image\image-w3600.png 2x" width="600" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" width="600"/><br />
</body>
</html>
下図の表示となります。一番解像度の大きい設定が利用される動作になります。
下図の表示となります。解像度が2倍の設定のため、表示画像の横幅は1200ピクセルになります。
こちらも、解像度の一番高い設定が利用されます。
widthを指定し、imgタグにsrcset属性を記述しますが、大きい解像度の画像に小さい画像を指定した場合にどのような表示になるかを確認します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset あり width指定(width=600)の表示 (逆転)</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 8x, image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" width="600" /><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 4x, image\image-w800.png 3x, image\image-w1800.png 2x, image\image-w3600.png 1x" width="600" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" width="600" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 3x, image\image-w1800.png 2x, image\image-w3600.png 1x" width="600" /><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 2x, image\image-w3600.png 1x" width="600" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" width="600" /><br />
</body>
</html>
解像度の最も高い設定ではなく、1xの記述が採用されます。この動作からsrcset内の各画像の大きさを判定して、表示される画像が選択されているようです。
高解像度のディスプレイの場合、2xの記述が採用されます。
先ほどの例では、width属性で画像の横幅を設定しましたが、style属性で横幅を設定した場合の動作を確認します。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset なしstyle width指定(width:600px)の表示</h2>
<img src="image\image-w400.png" style="width:600px" /><br />
<img src="image\image-w800.png" style="width:600px" /><br />
<img src="image\image-w1800.png" style="width:600px" /><br />
<img src="image\image-w3600.png" style="width:600px" /><br />
</body>
</html>
width属性を指定した場合と同様の結果になります。style="width:600px"
が指定されているため、image-w400.png の画像は引き延ばされて表示されます。
高解像度のディスプレイでの表示は下図となります。解像度が2倍の設定のため、表示画像の横幅は1200ピクセルになります。
image-w400.png, image-w800.png の画像は引き延ばされた表示になります。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset あり style width指定(width:600px)の表示</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 4x, image\image-w3600.png 8x" style="width:600px"/><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 1x, image\image-w800.png 2x, image\image-w1800.png 3x, image\image-w3600.png 4x" style="width:600px" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 4x" style="width:600px" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 1x, image\image-w1800.png 2x, image\image-w3600.png 3x" style="width:600px" /><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 1x, image\image-w3600.png 2x" style="width:600px" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" style="width:600px" /><br />
</body>
</html>
下図の表示となります。一番解像度の大きい設定が利用される動作になります。
下図の表示となります。解像度が2倍の設定のため、表示画像の横幅は1200ピクセルになります。
こちらも、解像度の一番高い設定が利用されます。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<h2>srcset あり style width指定(width:600px)の表示</h2>
<img src="image\image-w400.png" srcset="image\image-w400.png 8x, image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" style="width:600px"/><br />
<img src="image\image-w400.png" srcset="image\image-w400.png 4x, image\image-w800.png 3x, image\image-w1800.png 2x, image\image-w3600.png 1x" style="width:600px" /><br />
<hr />
<img src="image\image-w800.png" srcset="image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" style="width:600px" /><br />
<img src="image\image-w800.png" srcset="image\image-w800.png 4x, image\image-w1800.png 2x, image\image-w3600.png 1x" style="width:600px" /><br />
<hr />
<img src="image\image-w1800.png" srcset="image\image-w1800.png 2x, image\image-w3600.png 1x" style="width:600px" /><br />
<hr />
<img src="image\image-w3600.png" srcset="image\image-w3600.png 1x" style="width:600px" /><br />
</body>
</html>
解像度の最も高い設定ではなく、1xの記述が採用されます。この動作からsrcset内の各画像の大きさを判定して、表示される画像が選択されているようです。
高解像度のディスプレイの場合、2xの記述が採用されます。
記述の違いによる動作を確認しました。マシンによって動作が違ったりするため、結論としては、どういう基準で解像度に応じた画像が選択されるのか、よくわかりません。
とはいえ、ピクセル密度記述子利用して、小さい画像を大きい画像として設定すると誤動作の原因になる可能性が高そうです。
srcsetは多くの場合で、高い解像度の画像が優先的に使われるように見えますので、高解像度のディスプレイでない場合でも高解像度画像が参照されるケースがあるように見受けられます。
また、widthやスタイルでピクセル数を指定した場合、高解像度ディスプレイではディスプレイの実ピクセル数ではなく、倍率を考慮したピクセル数で表示されることがわかります。
(400pxと設定しても、拡大率200%のディスプレイでは800ピクセル幅で画像が表示されます。)