All about images

Just as links, images can feel pretty straightforward. Put an <img> tag, an src and an alt attributes and you're good right?!

Well yeah but... what if we could do much more, like loading the right image size depending on viewport, let the browser decide between image formats or even only load images when they are in the viewport?

Load the right image size and density

The <img> element has an srcset attribute that allows you to add several links to several versions of your image. You can do two things with srcset:

  1. Ask the browser to change the image depending of the width of the viewport.
  2. Ask the browser to change the image depending of the pixel density of the display.

In the example below, I have 4 versions of the same image that I want the browser to use when the viewport is less than 300, 600, 900 and 1200 pixels in width:

<img
    src="img-1200.jpg"
    srcset="img-300.jpg 300w, img-600.jpg 600w, img-900.jpg 900w, img-1200.jpg 1200w"
/>

And for pixel density for 1k, 2k or 4k screens:

<img
    src="img-1k.jpg"
    srcset="img-1k.jpg 1x, img-2k.jpg 2x, img-4k.jpg x4"
    alt="this is an image"
/>

But you can also combine them, for example for a favicon:

<img
    src="icon32px.png"
    "icon32px.png 32w, icon64px.png 64w, icon-retina.png 2x icon-ultra.png 3x icon.svg"
    alt="this is an image"
/>

This way you are sure you only load the right size or density for your readers.

Load the right image format

You maybe saw it before and wondered what was the <picture> element good for? Well it's quite simple, it's used to contain several <source> elements and an <img> element.

The <source> elements are used to give alternate versions of the same image. The most obvious use-case is to load several formats to allow to browser to pick the lighter if it supports it.

Let's take an example with a jpg and a webp.

<picture>
    <source srcset="img1.webp" type="image/webp">
    <img src="img1.jpg" alt="this is an image" />
</picture>

If the browser supports the webp format, it will automatically use the webp file instead of the jpg. Please note that if the browser does not support the <picture> element the <img> one will still work, so there is no good reason to not use them.

Lazy loading images

Lazy loading has become native in most browsers and is quite simple to use: loading:"lazy" on your <img> element and you are good to go. They are several ways of doing lazy loading for older browsers who don't support this feature. All of them require to use JavaScript. If you want to support old browsers, take a look at this article.

Combine all this together!

But you don't have to choose between all these features, you can combine them to have images at the right size, of the best type, only loaded when in the viewport, and all this only in HTML.

<picture>
    <source
    type="image/webp"
    srcset="img-300.webp 300w, img-600.webp 600w, img-900.webp 900w, img-1200.webp 1200w">
    <img
    loading="lazy"
    src="img.jpg"
    srcset="img-300.jpg 300w, img-600.jpg 600w, img-900.jpg 900w, img-1200.jpg 1200w" alt="The happy hacking keyboard">
</picture>

Knowing that images are the most heavy thing loaded by websites, it's incredible that this syntax isn't more known and used!

About svg files

The SVG format (for Scalable Vector Graphics) is using vector graphics with an XML markup language. It can therefore used in a browser as inline code to display images, which is a good thing as it reduces the number of requests made by the browser.

Here's a few tips:

SVG can be informative or decorative and its purpose can change the way you handle accessibility. If you are using an SVG for informative purposes (like a graph), you should add a <title> to add a tooltip and/pr an aria-label attribute to just vocalize it.

<svg role="img" aria-label="Accessible Name">
  <title>Accessible Name</title>
  <!-- child elements of the inline SVG -->
</svg>

If the SVG is used for decorative purposes (like an icon) you can simply hide it using aria-hidden="true".

<svg role="img" aria-hidden="true">
  <!-- child elements of the inline SVG -->
</svg>

Next: All about video and audio


Initially published: November 23rd, 2020
Generated: November 12th, 2021