Accessible images, pictures and SVGs
Tags: web, html, a11y
Published: 2023-02-02 08:06:45

---
title: Accessible images, pictures and SVGs
published: true
description: How to write accessible HTML for images, pictures and SVGs. 
tags: #web #html #a11y
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/szftb5sr5y2l6n9159jy.jpg
# published_at: 2023-01-21 19:34 +0000
---
> *Author of cover image is Marek Piwnicki*

## Accessible images

Images are an important part of any web app. We are using them for a lot of different purposes: decoration of text content, information about interactive UI, logos and icons. And how many goals we have for images, so many problems we meet in everyday routine. How to make image accessible? How to load different image for different device? What to do with `<svg />`? Animated `<svg />`?! Through this guideline, I want to solve these main, common problems with accessible images in web.

As always, I want to refer to [W3C guidelines](https://www.w3.org/WAI/tutorials/images/), as the source of most reliable and safe information. It splits images by several categories, we will check few of them in detail. But it doesn’t describe how to optimise images, which image format to use, we will check these topics too. Let’s start with categories.

Why we can’t just put image to DOM with `<img src=”my/image.jpeg” />` and keep it like this? Because:
* User may use your site with a screen reader.
* Your site needs to have proper Search Engine Optimisation.
* User could use your site from difference devices/screens.
* User could browse your site with bad internet connection.

### Simple setup

If the image is simple enough, that you could describe it with one sentence, or it presents simple information, a small piece of data, we could use `<img />` with `alt` attribute.

![A white owl](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5k5dhsuqgrw37r5tu06a.jpg)

```HTML
<img src=”my/img.jpeg” alt=”A white owl” />
```

Simple rules for `alt` content:
* Do not use words “picture”, “image of”, “pic of”.
`<img src=”my/img.png” alt=”picture of beautiful white owl” />`
* Describe shortly what is going on in the image.
* Provide instruction if needed instead of describing image’s content.
* Add small explanation for images with icon role.

Providing `alt` attribute also helps for SEO – some search engines rely on it for “understanding” content of images on your site.

### Decorative images

We often use images to decorate content: add snowfall to the site ❄️, add emotions for phrases 😂, create special mood 🌓. For this type of images, we have a really simple rule – keep `alt` attribute empty.

![Abstract texture](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wiu11wfb8gjd1h356gay.jpg)
_Texture for background image_

```HTML
<img src=”src.jpeg” alt=”” />
```

Attribute `role=”presentation”` also allow skipping this image for screen-readers. If we do not add empty `alt` attribute to `<img />` tag, screen readers will find and pronounce `src` attribute of image, that can confuse users. And do not put whitespace accidentally, `alt` attribute will be not hidden from screen readers then.

### Functional Images

If you have buttons with only image as content - you need to add simple description as: “what will happen if I will click on button”:

![Printer icon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0ubq1u0023i11xacq46.jpg)

```HTML
<img src=”src/print.png” alt=”print the form” />
```

You should never use image as a single source of truth. Always add text or tooltip for icon, that could be an action too and have some sense in text. You can add, at least, title attribute.

### Graphs and charts

Sometimes we have a very complex image that represents some data: image of a table, a graph or maybe screenshot of some chart. In this situation, we can’t describe image with simple sentence, but user of screen reader or search engine could have profit of reading data of image. Tag `<figure />` will help us in with the problem:

![Graph with Vite vs Webpack data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u8xad41l2p0skf0iwb22.jpg)

```HTML
<figure role="group">
    <img src="chart.png"
         alt="Interest about Vite and Webpack over the year" />
    <figcaption>
        On graph we can see, that Vite is on the pick of popularity with rate 100, webpack has stable 13 points of popularity WorldWide. 
    </figcaption>
</figure>
```

So then we associate an image with provided text. If this text shouldn’t be in site content - we can visually hide `<figcaption />` from user:

```CSS
.visually-hidden {
  position: absolute;
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  padding: 0 !important;
  margin: -1px !important;
  overflow: hidden !important;
  clip: rect(0,0,0,0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}
```

### SVG

Often, sites have SVG icons for logotypes, as secondary icons or even as a hero picture. We are using them to provide better quality of content, to inline image or animate it. But how to do `<svg />` content more accessible?

Let’s imagine that we have this SVG:

```HTML
<svg height="100" width="100">
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
```

First, let’s add `<title />` tag to the body:

```HTML
<svg height="100" width="100">
  <title>Red Circle</title>
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
```

Hmm, what if our `<svg /> `asks for proper description? Let’s add `<desc />` tag:

```HTML
<svg height="100" width="100">
  <title>Red Circle</title>
  <desc>Red circle with black border and transparent background</desc>
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
```

Also, let’s add `role=”image”` attribute, to make browser “think” that this bunch of SVG tags are single image:

```HTML
<svg height="100" width="100" role=”image”>
  <title>Red Circle</title>
  <desc>Red circle with black border and transparent background</desc>
  <circle cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
</svg>
```

### User Generated Content

A lot of content on the Internet is user generated. Users are loading photos, custom thumbnails for articles, user avatars. How to make this content accessible? There is a complex solution - check what is on photo, add keywords to `alt` attribute as Twitter does. Yeah, sounds almost impossible. As simple solution - you could provide to user an input, where users could describe pictures or even add `alt` attribute. 
I agree, we can’t do this for every image, but we could add “speculative” `alt` attribute, for example, we could add `alt=”Profile picture of user @peact_tea”`. 

### Wrapping up

With all this content, we could say - easiest way to make image accessible is just adding `alt` attribute (even empty still works - `<img />` tag without it is not valid) to `<img />` tag made it accessible. Unless somebody wrote something unexpected here 😅. Add title attribute to SVG and icons, to buttons and links, that contains only images and never use image as single source of truth.

* (https://www.w3.org/WAI/tutorials/images/)[https://www.w3.org/WAI/tutorials/images/] - accessibility guidelines
* (https://squoosh.app/)[https://squoosh.app/] - optimise your images via squoosh