Skip to main content


TODO download and try:

See resources:

Best practices for web images:

Responsive images (srcset and sizes)

This contains many correct examples:

Bookmarklet: - See the source code and live site

The following are all valid sizes: - 100px - 33vw - 20em - calc(50vw-10px) The following is not a valid size: 25% (percentages cannot be used with the sizes attribute)

The resource specified by the src attribute should be large enough to work well on all device sizes.

Not specifying sizes means sizes="100vw"

Responsive Images: If you’re just changing resolutions, use srcset. Suggests not to use sizes, just srcset, but assumes that the image will be 100% width (ie sizes="100vw"): → If you try it out, by switching between different devices in the browser developer tools responsive mode, this is the simplest solution and the one that gives the best result, without thinking. For phones it picks the right size. And for laptops it picks the largest, even if the image is displayed with max-width, but it doesn't matter much since it's a device that probably has a good Internet connection.

sizes="(min-width: 800px) 50vw, 100vw"

“If the browser window is wider than 800px, this image is probably going to be displayed about half the size of that. If it’s smaller, it’ll probably be full-width.”

Also see

Leaving sizes off entirely. Without it, the browser defaults to an implicit sizes value of 100vw, which, for important images that will probably be fairly large no matter the layout, isn’t a bad guess. Small, low-res viewports still get small images; big, hi-res viewports still get big ones. We avoid duplicating layout information and muddling our content and presentation.


<img src="elva-fairy-800w.jpg"
srcset="elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 600px) 480px,

docs - source - live site

When you resize above 520 it loads the 1600px:

/img/cartell-garrinada-2023-800.jpg 800w,
/img/cartell-garrinada-2023-1600.jpg 1600w
sizes="(max-width: 520px) 50vw,
alt="Cartell Garrinada 2023"
<img src="flower-large.jpg"
srcset="flower-small.jpg 480w,
flower-large.jpg 1080w"

Density descriptors:

<img src="flower.jpg"
srcset="flower-1x.jpg 1x,
flower-2x.jpg 2x,
flower-3x.jpg 3x"

Easy to understand article:

Multiple slot widths:

<img src="flower.jpg"
srcset="flower-small.jpg 480w,
flower-large.jpg 800w"
sizes="(max-width: 480px) 100vw,
(max-width: 1024px) 50vw, 800px"

Multiple formats (JPEG, WEBP and AVIF)

Important: order matters. The browser will load the first one it supports.


<source type="image/avif" srcset="images/news/news-detail-header.avif" />
<source type="image/webp" srcset="images/news/news-detail-header.webp" />
<source type="image/jpeg" srcset="images/news/news-detail-header.jpeg" />
class="img-fluid news-detail-image"
alt="fine dining experience"

Image Magick

CLI docs:

ImageMagick Examples -- Resize or Scaling (General Techniques):

convert cartell.jpg -resize 50% cartell-garrinada-50.jpg
convert foto.jpg -resize 1080 foto-1080.jpg
convert foto.jpg -resize 1080x1920 foto-1080x1920.jpg

Make Instagram portrait 4:5. Eg if we have a DIN-A4 image and we want to add some black borders at the sides so that the image is not cropped at the top and bottom.

convert image.jpeg -gravity center -background black -resize 1080x1350 -extent 1080x1350 image-instagram.jpeg


Comes installed in macOS.


sips -z <height> <width> <image> resizes the specified image, ignoring the previous aspect ratio.

sips -Z <size> <image> resizes the largest side of the specified image, preserving the aspect ratio.

sips -c <height> <width> <image> crops the specified image to the given dimensions (relative to the center of the original image).

sips -r <degrees> <image> rotates the image by the specified degrees.

By default, sips will destructively overwrite the input image. Use the -o flag to specify a different output file path (which must have the same file extension as the input image).

Avoid layout shift

Avoiding <img> layout shifts: aspect-ratio vs width & height attributes -

If we don't know the exact aspect ratio, then use object-fit (source):

img {
aspect-ratio: 16 / 9;
width: 100%;
object-fit: cover;