How to serve sharp images for Retina screens
Short answer
List files for regular and dense screens in srcset — the browser picks the right one:
<img src="/media/photo-200x200.jpg"
srcset="/media/photo-200x200.jpg 1x, /media/photo-400x250.jpg 2x"
alt="A flower" width="200" height="200" style="object-fit: cover;">On a Retina screen (density 2) one CSS pixel is four screen pixels, and the image needs a file twice as large, otherwise it looks blurry. src stays as a fallback for old browsers.
Choosing by width
If the image stretches with the page, it is better to describe the width of each file with the w descriptor, and in sizes — how wide the image will be on screen:
<img src="/media/photo-400x250.jpg"
srcset="/media/photo-400x250.jpg 400w, /media/photo-800x500.jpg 800w"
sizes="(max-width: 600px) 100vw, 400px"
alt="A flower" width="400" height="250" style="max-width: 100%; height: auto;">The browser itself calculates which file is needed, given the window width and the screen density.
Icons and logos
For simple graphics SVG is more convenient: a vector image is sharp on any screen, and several files are not needed.
Common mistake
w descriptors are given, but sizes is forgotten. Then the browser assumes the image takes the full window width (100vw), and on a wide screen it loads the largest file even for a small preview.
Functions used in this recipe
- srcset — Several files of one image in different sizes: the browser picks the one that fits the screen.
- <img> — An image.
- <picture> — A container for several versions of an image: the browser picks a matching `<source>` or falls back to `<img>`.
- src — The address of the embedded file for `<img>`, `<video>`, `<audio>`, `<script>`, `<iframe>`.