HTML and CSS course Β· Module 10: Accessibility (a11y)

Accessible Images and Multimedia

7 min read
In this lesson7

A photo of Tutankhamun's golden mask hangs on the museum's website. A sighted person looks at it for a second, while a screen reader reads out the file name "IMG_0042.jpg" - or nothing at all. An image without a description is a blank wall to a blind pilgrim. In Ancient Egypt, every sculpture, painting and relief on a temple wall had its description - often carved next to it in hieroglyphs. Today we must do the same for visual content on the web, so that blind and visually impaired people can understand what our images and multimedia show.

Alternative Text (alt)

The alt attribute is the most important element of image accessibility. A screen reader reads it instead of showing the image, the browser displays it when the file fails to load, and search engines use it to understand what a graphic shows.

Rules for Writing alt

Before you write anything, decide: does this image carry information, or is it just decoration? A good alt for an informative image answers the question of what important thing the image conveys at this point on the page:

1<!-- 1. Describe WHAT is in the image, not what the file looks like -->
2<!-- BAD -->
3<img src="IMG_0042.jpg" alt="IMG_0042.jpg">
4<img src="pyramid.jpg" alt="pyramid">
5
6<!-- GOOD -->
7<img src="pyramid.jpg"
8     alt="The Great Pyramid of Giza against a sunset sky">
9
10<!-- 2. Be concise - 1-2 sentences -->
11<!-- BAD - too long -->
12<img src="mask.jpg"
13     alt="In the photo we see the golden death mask of the young
14     pharaoh Tutankhamun, which was discovered by Howard
15     Carter in 1922 in the Valley of the Kings and weighs about 11 kg
16     of pure gold with inlays of lapis lazuli and turquoise">
17
18<!-- GOOD -->
19<img src="mask.jpg"
20     alt="Golden death mask of pharaoh Tutankhamun with lapis lazuli inlays">

A file name and the single word "pyramid" say nothing, while an essay on the history of the mask wears the listener out, because the reader reads the alt in one go. Do not start with "The photo shows" either - the reader announces on its own that this is a graphic.

When Should alt Be Empty?

Decorative images that carry no informational content should have an empty alt attribute. Here are three typical situations:

1<!-- Decorative separator line -->
2<img src="border-pattern.png" alt="">
3
4<!-- Icon next to text that describes it -->
5<button>
6    <img src="search-icon.png" alt="">
7    Search
8</button>
9<!-- The text "Search" already describes the function, the icon is decorative -->
10
11<!-- Decorative background - better to use CSS -->
12<div style="background-image: url('papyrus-bg.jpg')">
13    <p>Article content...</p>
14</div>

An empty alt="" is a "skip me" signal. That is different from a missing attribute: without alt, many readers will read out the file name. The reader ignores CSS backgrounds completely, so they are a good place for decorations. When a button contains only an icon, the icon's alt becomes the button's name and must describe the action (alt="Search"), not the look (alt="magnifying glass"). The simplest option, though, is to add visible text, as in the example - and that is what I recommend.

The figure and figcaption Elements

When an image needs a visible caption - a date, an author or some context - wrap it in a <figure> element and add a <figcaption>:

1<figure>
2    <img src="rosetta-stone.jpg"
3         alt="The Rosetta Stone with three types of writing: hieroglyphs, Demotic script, and Greek">
4    <figcaption>
5        The Rosetta Stone (196 BCE) - the key to deciphering hieroglyphs,
6        discovered in 1799 by Napoleon's soldiers
7    </figcaption>
8</figure>

<figcaption> is a caption visible to all users, while alt is a description meant specifically for those who cannot see the image. Do not repeat the same thing in both: the alt says what is visible on the stone, and the caption adds its history. So the order of work is always the same: the decision, the alt, and finally, optionally, a <figure> with a caption.

Accessible Video

Captions

A video without captions excludes deaf people, but also anyone watching it on a tram without headphones. You add captions with a <track> element inside <video>:

1<video controls>
2    <source src="exhibition-tour.mp4" type="video/mp4">
3
4    <!-- Captions for deaf and hard of hearing -->
5    <track kind="captions" src="captions-en.vtt"
6           srclang="en" label="English" default>
7
8    <!-- Subtitles in another language -->
9    <track kind="subtitles" src="subtitles-pl.vtt"
10           srclang="pl" label="Polish">
11
12    Your browser does not support the video element.
13</video>

The kind attribute defines the type of track, srclang its language, and label its name in the player menu. default turns the track on automatically, and only one <track> may have it. The text before </video> is shown only by browsers without video support.

Difference Between Captions and Subtitles:

  • Captions - for deaf and hard of hearing people, also include sound descriptions: [background music], [footsteps]
  • Subtitles - translation of dialogue into another language

WebVTT Format

You store the captions themselves in a plain text file in the WebVTT format, with the .vtt extension. Such a file looks like this:

1WEBVTT
2
300:00:01.000 --> 00:00:04.000
4Welcome to the Ancient Egypt Museum.
5
600:00:04.500 --> 00:00:08.000
7We begin our journey from the Main Hall.
8
900:00:08.500 --> 00:00:12.000
10[footsteps on marble floor]

The file starts with the word WEBVTT, and each fragment is a start and end time (hours:minutes:seconds.milliseconds) followed by the text. The sound description in square brackets is exactly what distinguishes captions from a plain translation.

Accessible Audio

An audio recording has no picture on which captions could be displayed, so for deaf people you provide a transcript, that is, a full written record of the text:

1<figure>
2    <figcaption>
3        <h3>Audiobook: The Story of Cleopatra</h3>
4    </figcaption>
5    <audio controls>
6        <source src="cleopatra.mp3" type="audio/mpeg">
7        Your browser does not support the audio element.
8    </audio>
9    <!-- Transcript for deaf and hard of hearing -->
10    <details>
11        <summary>Recording Transcript</summary>
12        <p>Cleopatra VII Philopator, the last ruler
13        of the Ptolemaic dynasty...</p>
14    </details>
15</figure>

The <details> element hides the long transcript under a <summary> button, so it does not clutter the page, and it works from the keyboard without a single line of JavaScript.

Accessible SVG

An SVG graphic is code, not a file with an alt attribute, so you add its description differently - depending on whether the graphic carries information:

1<!-- SVG as informational image -->
2<svg role="img" aria-labelledby="chart-title chart-desc">
3    <title id="chart-title">Museum visitor count</title>
4    <desc id="chart-desc">
5        Bar chart showing visitor growth
6        from 50,000 in 2020 to 120,000 in 2024.
7    </desc>
8    <!-- SVG elements -->
9</svg>
10
11<!-- Decorative SVG -->
12<svg aria-hidden="true" focusable="false">
13    <!-- decorative graphic -->
14</svg>

role="img" tells assistive technology to treat the SVG as a single image, and aria-labelledby builds its description from <title> and <desc>. aria-hidden="true" hides a decoration only from the reader - it is still visible on screen. focusable="false" protects against old Internet Explorer, which could put focus on an SVG.

Prefers-reduced-motion

Some users are sensitive to animations - they can cause dizziness or nausea. The prefers-reduced-motion media query checks whether someone has turned on reduced motion in their system:

1/* Default animation */
2.slide-in {
3    animation: slideIn 0.5s ease-in-out;
4}
5
6/* Disable animation for users who prefer it */
7@media (prefers-reduced-motion: reduce) {
8    .slide-in {
9        animation: none;
10    }
11
12    * {
13        transition-duration: 0.01ms !important;
14        animation-duration: 0.01ms !important;
15    }
16}

The animation stays for those who want it and disappears only for people who asked for that. A duration of 0.01ms instead of zero means that elements jump straight to their final state, while scripts waiting for the end of an animation keep working.

Accessible multimedia is like the inscriptions next to Egyptian reliefs - they let everyone understand the message, whether they "see" the original or use its description. In the next lesson we will deal with color and contrast.

Practice

In the editor below you will find images, a video and an SVG. Check which of them are informative and which are decorative, and whether each has the right description:

Code for this lesson: index.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4    <meta charset="UTF-8">
5    <meta name="viewport" content="width=device-width, initial-scale=1.0">
6    <title>Accessible images and multimedia</title>
7    <link rel="stylesheet" href="style.css">
8</head>
9<body>
10    <h1>Accessible images and multimedia</h1>
11
12    <!-- Informative image with alt -->
13    <section>
14        <h2>Informative image</h2>
15        <figure>
16            <img src="https://placehold.co/500x300/d4af37/1a1a2e?text=Rosetta+Stone"
17                 alt="The Rosetta Stone with three types of writing: hieroglyphs, Demotic script, and Greek">
18            <figcaption>
19                The Rosetta Stone (196 BCE) - the key to reading hieroglyphs
20            </figcaption>
21        </figure>
22    </section>
23
24    <!-- Decorative image -->
25    <section>
26        <h2>Decorative image</h2>
27        <img src="https://placehold.co/600x4/d4af37/d4af37" alt="">
28        <p>The ornament above is decorative - it has an empty alt=""</p>
29    </section>
30
31    <!-- Accessible SVG -->
32    <section>
33        <h2>Accessible SVG</h2>
34        <svg role="img" aria-labelledby="svg-title svg-desc"
35             width="200" height="200" viewBox="0 0 200 200">
36            <title id="svg-title">Visitor statistics</title>
37            <desc id="svg-desc">Bar chart: 2022: 50k, 2023: 80k, 2024: 120k</desc>
38            <rect x="20" y="120" width="40" height="60" fill="#d4af37"/>
39            <rect x="80" y="80" width="40" height="100" fill="#8b6914"/>
40            <rect x="140" y="20" width="40" height="160" fill="#3d2914"/>
41            <text x="30" y="195" font-size="12" fill="#1a1a2e">2022</text>
42            <text x="90" y="195" font-size="12" fill="#1a1a2e">2023</text>
43            <text x="150" y="195" font-size="12" fill="#1a1a2e">2024</text>
44        </svg>
45    </section>
46
47    <!-- Video with captions -->
48    <section>
49        <h2>Video with captions</h2>
50        <video controls width="500" poster="https://placehold.co/500x300/1a1a2e/d4af37?text=Museum+Video">
51            <track kind="captions" srclang="en" label="English" default>
52            Your browser does not support the video element.
53        </video>
54        <p><em>An example of a video element with a track element for captions.</em></p>
55    </section>
56
57    <!-- Audio with a transcript -->
58    <section>
59        <h2>Audio with a transcript</h2>
60        <figure>
61            <figcaption><strong>Audiobook: The Story of Cleopatra</strong></figcaption>
62            <audio controls>
63                Your browser does not support the audio element.
64            </audio>
65        </figure>
66        <details>
67            <summary>Recording transcript</summary>
68            <p>Cleopatra VII Philopator, the last ruler of the Ptolemaic
69               dynasty, reigned in Egypt from 51 to 30 BCE.
70               Known for her intelligence and charisma, she spoke many languages...</p>
71        </details>
72    </section>
73</body>
74</html>

Remember: alt text, captions and transcripts are the hieroglyphs carved next to a relief - they tell the same story to those who cannot see or hear it.

Spotted a mistake in this lesson?

Check yourself

Answer the questions from this lesson. Pick an answer to see right away whether it is correct.

  1. 1. When should an image have an empty alt="" attribute?

  2. 2. When should you use the aria-hidden="true" attribute?

These are 2 of 3 questions for this lesson. Solve the rest in the game.

Hands-on tasks in the game

  • Vertical ordering

    Arrange the steps for adding an accessible image from the beginning:

  • Code editor

    Add alt to an informational image with figcaption, alt="" to a decorative one, text to an icon button, and role="img" with title/desc to an SVG.

  • Code editor

    Add a video with captions (track), audio with a transcript in details, and CSS @media (prefers-reduced-motion: reduce) to disable animations.

  • Horizontal ordering

    Arrange the correct track element for video captions:

Useful articles