Atoms
Icon and Icon Box
A small glyph that helps people recognise something, on its own or in a frame.
Code
<span class="inline">
<svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Bell"/></svg>
<span class="text">Rota reminder</span>
</span>
Why it exists
An icon helps someone spot what they already know: a warning beside an error, an arrow on a Link. Few icons mean the same thing to everyone, so an icon sits beside the word and doesn’t replace it.
Every icon comes from one sprite, drawn as one family. It’s sized in em and coloured with currentColor, so it follows its text without being told, in any theme and in forced colours. Inside a control or beside text it adds nothing for a screen reader, so it stays hidden there.
An Icon Box is a frame for the moments an icon needs to line up with controls or carry more weight, as in an Empty State. It isn’t interactive. That job belongs to an icon Button.
When to use
- Beside text, to speed recognition: a warning on an error, an arrow on a Link.
.icon-boxto line icons up with controls, or to give one more weight, as in an Empty State.- Not instead of a word that people need, unless the control has a hidden name.
Rules
- Every icon carries
width="1em" height="1em", so it stays text-sized if CSS fails to load. - Decorative icons (beside text, or inside a named control) carry
aria-hidden="true" focusable="false". A meaningful standalone icon takesrole="img"andaria-label, or its control carries the name. - Intent colours an icon but never carries meaning alone (WCAG 1.4.1). For muted icons, use the text colour utilities (
.text-color-muted). - Never draw icons inline with
strokepaths. If the sprite lacks a glyph, add it toicons/icons.svgand runnpm run sync:icons.
Hide It or Name It
Code
<!-- Decorative icon beside text -->
<svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Check"/></svg>
<!-- Directional icon: mirrors in right-to-left text -->
<svg class="icon icon--dir" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#ArrowRight"/></svg>
<!-- Size and intent -->
<svg class="icon icon--lg icon--success" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Check"/></svg>
<!-- Meaningful standalone icon -->
<svg class="icon icon--warning" width="1em" height="1em" role="img" aria-label="Warning"><use href="#Warning"/></svg>
Give an Icon More Weight
The box is decoration, so it’s hidden, and the text beside it says what it means.
Code
<span class="inline">
<span class="icon-box" aria-hidden="true">
<svg class="icon" width="1em" height="1em" aria-hidden="true" focusable="false"><use href="#Bell"/></svg>
</span>
<span class="text">Rota reminder</span>
</span>
Do and Don’t
| Do | Don’t |
|---|---|
Add a missing glyph to icons/icons.svg and run npm run sync:icons. | Draw an icon inline with stroke paths. |
| Hide an icon beside text from screen readers. | Make a screen reader read “check” before “Saved”. |
| Pair an intent colour with words. | Use a red icon as the only sign of an error. |
Use --dir on arrows, so they mirror in right-to-left text. | Mirror an icon that has no direction, like a tick. |
In Storybook
See also
- Button: An action on the page, such as saving a Form, opening a Dialog or changing a setting.
- Badge, Status, Chip and Kbd: Small labels chosen by their job, such as a count on something, the state of something, a value someone chose or a key to press.
- Avatar and Avatar Group: Who someone is, as a photo, initials or an icon in a shape.