Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Responsive images

A photo 800 pixels wide does not fit on a phone screen, and a huge file for a small screen wastes traffic. Responsive images solve both problems: CSS fits the picture into its place, and HTML lets the browser choose a suitable file.

A fluid image

By default an <img> is shown at its real size and can stick out over the edge. Two properties make an image fluid — shrinking together with its parent:

<style>
  img { max-width: 100%; height: auto; }
</style>
 
<img src="/media/photo-800x500.jpg" alt="A river in the mountains" width="800" height="500">

max-width: 100% forbids it to be wider than the parent, height: auto keeps the proportions. The width and height attributes are still worth setting: they let the browser reserve the space in advance, so the text does not jump while the picture loads.

Proportions: aspect-ratio

The aspect-ratio property sets the ratio of a block's sides: the width stretches, and the height is calculated by itself. This is how space is prepared for a video or a preview:

<style>
  .video { aspect-ratio: 16 / 9; max-width: 320px; background: black; color: white; display: grid; place-items: center; }
</style>
 
<div class="video">16 : 9</div>

Filling: object-fit

When an image gets both a width and a height, it gets distorted. object-fit says how to fit it into the frame:

<style>
  .row { display: flex; gap: 8px; }
  .row img { width: 140px; height: 140px; border: 2px solid gray; }
  .cover { object-fit: cover; }
  .contain { object-fit: contain; }
</style>
 
<div class="row">
  <img src="/media/photo-400x250.jpg" alt="Stretched">
  <img class="cover" src="/media/photo-400x250.jpg" alt="cover">
  <img class="contain" src="/media/photo-400x250.jpg" alt="contain">
</div>
ValueResult
fillStretches, the proportions break (the default)
coverFills the whole frame, the excess is cut off
containFits completely, empty margins remain

Choosing a file: srcset and sizes

The srcset attribute lists several versions of one picture with their widths — 400w means "a file 400 pixels wide". The sizes attribute hints how wide the picture will be on the page. The browser downloads the most suitable file by itself:

<style>
  img { max-width: 100%; height: auto; }
</style>
 
<img
  src="/media/photo-800x500.jpg"
  srcset="/media/photo-400x250.jpg 400w,
          /media/photo-800x500.jpg 800w"
  sizes="(max-width: 500px) 100vw, 500px"
  alt="A river in the mountains" width="800" height="500">

The sizes value reads like this: on a screen up to 500 pixels the picture is as wide as the window, otherwise it is 500 pixels. How images affect loading speed is covered in the lesson "Page speed".

The picture element

<picture> is needed when different screens show different pictures — for example, a wide shot on a computer and a square one on a phone. The browser takes the first <source> whose media condition matches, and <img> serves as the fallback:

<picture>
  <source media="(min-width: 600px)" srcset="/media/photo-600x200.jpg">
  <img src="/media/photo-200x200.jpg" alt="A river in the mountains">
</picture>

The narrow square shot appears if you narrow the browser window until the example is under 600 pixels wide.

Common mistake

Giving an image width: 100% and a fixed height produces a squashed photo:

<style>
  .bad { width: 100%; height: 120px; }
  .good { width: 100%; height: 120px; object-fit: cover; }
</style>
 
<img class="bad" src="/media/photo-800x500.jpg" alt="Squashed">
<img class="good" src="/media/photo-800x500.jpg" alt="Neatly cropped">

Either keep height: auto, or add object-fit: cover.

Thanks for reading!

Donate to the site — we work hard for you.