Images can be made accessible by either marking them as decorative or by providing an alternative text. Which technique to choose depends on the way the image has been implemented (as an img
or SVG
element, or with CSS). Not only images need a text alternative: when textual characters are used in a way that differs from their literal meaning, they also require an alternative text.
We discuss the difference between decorative and informative images in our article on how to write high quality text alternatives for images in different contexts.
Contents
The accessibility tree
Browsers provide information to assistive technologies via the accessibility tree.
- Marking an image as decorative removes it from the accessibility tree. Screenreader users will hear nothing when encountering said image, and won't even know an image is present on their screen.
- The below techniques can be used to add an accessible name to an informative image in the accessibility tree.
- When a screenreader comes across an image, it will read the accessible name.
- When someone uses voice recognition software, they can use the accessible name of an element to activate it.
Your browser's developer tools allow you to visualise the contents of the accessibility tree. The following example shows how to inspect the AnySurfer logo in Chrome.
- Select the tab 'Accessibility'.
- Under 'computed properties' you'll see:
- Name: 'AnySurfer home'
- Role: img
The img
element
Images implemented with <img />
, <input type="image" />
, and <area />
always need an alt
attribute.
Decorative image
Leave the alt attribute empty if an image is decorative. This attribute must be present, but empty: it shall not include any characters, not even a space. For example:
<img alt="" src="flowers.png" />
An empty alt attribute removes the image from the accessibility tree. This example shows a logo with an empty alt attribute. The accessibility tree says 'Accessibility node not exposed'.
An empty alt attribute is not the same as a missing alt attribute. When the alt attribute is missing, the image is still present in the accessibility tree. It will have an img role, but no name. When this occurs, assistive technology will try to guess the name and will often opt for the file name.
A missing alt attribute is a violation of the HTML standards.
Informative image
When informative images are implemented with an <img />
or <input type="image" />
, use the alt
attribute to provide them with alternative texts.
This logo links to the AnySurfer website:
<a href="https://www.anysurfer.be">
<img alt="Home AnySurfer" src="logo.png" />
</a>
This magnifying glass is a search button:
<input alt="Search" src="magnifyinglass.png" type="image" />
The SVG
element
When an SVG
element is used to implement an image, you need ARIA attributes to make it accessible. Find out how in our article Using ARIA to enhance SVG accessibility.
Decorative SVG
Use aria-hidden="true"
to remove decorative SVG images from the accessibility tree.
<svg aria-hidden="true"></svg>
Informative SVG
- Add the ARIA attribute
role="img"
to theSVG
element. This ensures the component is seen as an image by the accessibility tree. -
Use the
title
element to add a text alternative to an informative image.<svg role="img"><title></title> </svg>
- Some articles recommend the use of an
aria-labelledby
attribute to connect the content of thetitle
element with the corresponding SVG. However, the Deque tests show no difference between the 5th (no extra connection) and 8th pattern (uses anaria-labelledby
).
With CSS
You can insert an image with CSS by using a background URL, or the :before and :after pseudo-elements.
Decorative CSS image
You don't have to do anything to mark the image as decorative. It won't appear in the accessibility tree.
Informative CSS image
The following example shows a Twitter link, using CSS to insert the Twitter logo:
<a class="twitter" href="https://twitter.com/anysurfer">
</a>
a.twitter:after {
content:url('icon_twitter.png');
}
This informative image needs a text alternative. The easiest way to implement one is to use hidden text. An aria-label
can also be used, depending on the circumstances.
Hidden text
This technique is used to add a piece of text in the HTML code that's visually hidden, but which is used by the accessibility tree to provide an accessible name for your image.
<a class="twitter" href="https://twitter.com/anysurfer">
<span class="visuallyhidden">Twitter</span>
</a>
a.twitter:after {
content:url('icon_twitter.png');
}
.visuallyhidden {
border: 0;
clip: rect(0 0 0 0);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
}
Read more about this technique in this WebAIM article about hidden texts.
Using an aria-label
The attribute aria-label
can also be used to give a component an accessible name. The following example shows how to use it to give this Twitter icon a text alternative.
<a aria-label="Twitter" class="twitter" href="https://twitter.com/anysurfer">
</a>
a.twitter:after {
content:url('icon_twitter.png');
}
This hidden text technique can be used in any context. If you opt to use an aria-label
instead, remember that an aria-label
only works for elements that have a role, and that the contents of the aria-label
will overwrite any other texts. Find out more in our article about aria-label and aria-labelledby.
Textual characters
Sometimes characters are used for their looks rather than their literal meaning. Just like images, they can be identified as decorative or informative when used like this. They're not real images, but still need a text alternative sometimes.
Emoticons
Emoticons are rarely decorative. They're used to give extra meaning to a message, or to indicate how a reader should interpret your words. Not everyone knows how to interpret the specific strings of characters used to form emoticons. Make your emoticons accessible:
- Hide the characters with
aria-hidden="true"
. - Add an alternative text by using the hidden text technique mentioned earlier
(class="visuallyhidden)
.
For example:
<span aria-hidden="true">:/</span>
<span class="visuallyhidden">(melancholic)</span>
Emoji
When an emoji is decorative, it must be removed from the accessibility tree. Insert the emoji in a span
, and add aria-hidden="true"
. Take this little airplane used on the website of an airline company, for example:
Fly to the sun!
<span aria-hidden="true">✈</span>
When an emoji is informative:
- Place the emoji in a
span
element: this enables you to add attributes. - Give it the role of an image with
role="img"
. - Use an
aria-label to give it an alternative text.
Are we going by<span aria-label="train" role="img">🚆</span> or by <span aria-label="airplane" role="img">✈</span>?
Are we going by 🚆 or by ✈?
Other characters
The X or the multiplication sign is often used to signify a "close" button. Visually, it looks like a cross: a sighted user will understand the character signifies a close button. a screenreader user hears "Button X" which is not meaningufl.
- Hide the character with
aria-hidden="true"
, and add an alternative text with hidden text, - Or give the button an
aria-label
. The content of thearia-label
will overwrite the button's original content:
<button aria-label="Close">
×</button>
Icon fonts
Icon fonts use certain characters not for their original meaning, but to add an icon instead. To make icon fonts accessible, combine the techniques mentioned above.
Decorative icon font
The inserted character will appear in the accessibility tree, but will be meaningless for screenreader users. Hide it with an aria-hidden="true"
. The character must be implemented with a span
rather than being added to the element itself for this technique to work.
Bad example:
<button class="icon" data-icon="p"></button>
.icon:before {
font-family: 'icomoon';
content: attr(data-icon);
}
Good example:
<button>
<span aria-hidden="true" class="icon" data-icon="p"> </span></button>
.icon:before {
font-family: 'icomoon';
content: attr(data-icon);
}
Informative icon font
Remove the character from the accessibility tree, and give it a text alternative. The following example uses an aria-label
to accomplish this. The contents will be overwritten and therefore don't need to be hidden first.
<button aria-label="Play" class="icon" data-icon="p"></button>
.icon:before {
font-family: 'icomoon';
content: attr(data-icon);
}
If this technique isn't an option, hide the character with aria-hidden="true"
, then add the text alternative with a hidden text (class="visuallyhidden").
Comments
Be the first to comment