Cmpnts

Menu

Atoms

Icon and Icon Box

A small glyph that helps people recognise something, on its own or in a frame.


Rota reminder
Code
HTML
<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-box to 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 takes role="img" and aria-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 stroke paths. If the sprite lacks a glyph, add it to icons/icons.svg and run npm run sync:icons.

Hide It or Name It

Code
HTML
<!-- 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.

Rota reminder
Code
HTML
<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

DoDon’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.

Search the docs