Icons are inline SVG elements wrapped in a container class. They inherit colour from the surrounding text, maintain a fixed square aspect ratio, and are accessible by default.


Principles

  • Inline SVG only — never use <img> tags for icons. Inline SVGs allow colour inheritance and eliminate extra HTTP requests.
  • currentColor always — all icon <path> elements must use fill="currentColor" so the icon inherits the parent's text colour. This keeps icons visually consistent across themes and contexts.
  • No xmlns — strip xmlns and xmlns:xlink attributes from inline SVGs. They are only needed for standalone files, not inline usage.
  • Square aspect ratio — icons are always 1:1. Use viewBox to define the coordinate system, not width/height.
  • Brand icons only — do not use Material Design, Font Awesome, Heroicons, Feather, or any other third-party icon source. Use the brand icons from assets/images/svg-icons/. If no icon exists for your need, request one from the design team.

Icon Wrapper

Use to wrap inline SVG icons. This class constrains the icon to a fixed size and enforces the square aspect ratio.

<div class="svg-icn" data-icon="arrow-right">
  <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none">
    <path d="M5 12h14M12 5l7 7-7 7" fill="currentColor"/>
  </svg>
</div>

Properties

Property Value Purpose
width 1.5rem Standard icon size
height 1.5rem Matches width for square
display flex Enables centering
justify-content center Horizontal centering
align-items center Vertical centering
aspect-ratio 1 / 1 Enforces square shape

data-icon attribute

Always include a data-icon attribute with a descriptive name. This makes icons identifiable in code — raw SVG paths are unreadable without it.

<div class="svg-icn" data-icon="chevron-down">...</div>
<div class="svg-icn" data-icon="close">...</div>
<div class="svg-icn" data-icon="search">...</div>

Use lowercase kebab-case for icon names (e.g. arrow-right, chevron-down, external-link).


Icon in Buttons

For icon-only buttons, use on the button and as the SVG wrapper.

<button class="button is-icon" aria-label="Close">
  <div class="svg-icn">
    <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none">
      <path d="M18 6L6 18M6 6l12 12" fill="currentColor"/>
    </svg>
  </div>
</button>

See the Button documentation for full button modifier details.


SVG Requirements

Every icon SVG must follow these rules before being added to the codebase:

Rule Required Example
fill="currentColor" Yes Inherits text colour from parent
viewBox attribute Yes viewBox="0 0 24 24" defines the coordinate space
No xmlns Yes Strip xmlns and xmlns:xlink — not needed inline
width="100%" height="100%" Yes SVG fills its wrapper; sizing is controlled by the wrapper class
fill="none" on <svg> Yes Prevents default black fill; paths use fill="currentColor" individually
No XML comments Recommended Remove <!-- ... --> comments for cleaner code

Standard viewBox

Use 0 0 24 24 as the default icon grid. If an icon uses a different coordinate system, preserve its original viewBox — do not rescale manually.


Accessibility

  • Decorative icons — add aria-hidden="true" to the SVG when the icon is purely visual and accompanied by text.
  • Meaningful icons — add aria-label to the parent element (e.g. the button) when the icon conveys meaning without visible text.
  • Icon buttons — always include aria-label on the <button> element.
<!-- Decorative: icon next to text -->
<div class="svg-icn" data-icon="check">
  <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M20 6L9 17l-5-5" fill="currentColor"/>
  </svg>
</div>

<!-- Meaningful: icon button with no visible text -->
<button class="button is-icon" aria-label="Close menu">
  <div class="svg-icn">
    <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path d="M18 6L6 18M6 6l12 12" fill="currentColor"/>
    </svg>
  </div>
</button>

Colour

Icons inherit colour through currentColor. To change an icon's colour, change the text colour of its parent — never hardcode a fill value.

<!-- Icon inherits the faded text colour -->
<div class="text-faded">
  <div class="svg-icn" data-icon="info">
    <svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <path d="M12 2a10 10 0 100 20 10 10 0 000-20zm1 15h-2v-6h2v6zm0-8h-2V7h2v2z" fill="currentColor"/>
    </svg>
  </div>
</div>

Icon Shorthand

Use {{icon:name}} in any markdown file processed by the doc generator to render an inline icon. The shorthand is expanded at build time — the actual SVG is read from assets/images/svg-icons/ and injected as a standard wrapper.

{{icon:check}}         → renders the check icon
{{icon:arrow-right}}   → renders the arrow-right icon
{{icon:t-shirt}}       → renders the t-shirt icon

The name must match a key from the icon registry below. If the name is not found, a warning is logged during generation and an HTML comment is output instead.

This shorthand only works in files processed by cms/generator/generate-docs.js — it does not work in standalone HTML pages.


SVG Cleaner Tool

Use the SVG Cleaner to prepare icons before adding them to the codebase. The tool automates the required cleanup:

  • Strips xmlns attributes
  • Sets fills to currentColor (when enabled)
  • Wraps in with data-icon attribute (when "Icon" is checked)
  • Strips XML comments
  • Optional minification

For CLI usage:

echo '<svg>...</svg>' | node assets/js/svg-clean.js --current-color --icon --icon-name arrow-right --strip-comments

Naming Conventions

Convention Example
Lowercase kebab-case arrow-right, chevron-down
Describe the shape, not the function arrow-right not go-forward
Use directional suffixes chevron-up, chevron-down, chevron-left
Use common icon vocabulary close, search, menu, check, plus, minus

Rules

Do Don't
Use fill="currentColor" on all paths Hardcode hex colours in SVG fills
Use to wrap all icons Use <img> tags for icons
Include data-icon with a descriptive name Leave icons unnamed
Include aria-hidden="true" on decorative icons Omit accessibility attributes
Include aria-label on icon-only buttons Rely on the icon alone to convey meaning
Use the SVG Cleaner to prepare icons Manually edit SVG attributes
Strip xmlns from inline SVGs Keep attributes meant for standalone files
Use width="100%" height="100%" on SVGs Use fixed pixel/rem sizes on the SVG element
Use fill="none" on the <svg> element Omit fill on <svg> (defaults to black)
Use wrapper to control icon size Size icons via width/height on the SVG
Check the registry before using any icon Use external icon libraries as a fallback

Requesting a New Icon

If you need an icon that is not in the brand icon set:

  1. Check the brand book — the icon you need may exist under a different name. See the Visual Identity page for the full icon grid.
  2. Document the request — describe the concept, intended size, and where it will be used
  3. Submit to the design team — new icons must match the existing style (24x24 grid, single-colour, rounded corners)
  4. Do not use a placeholder — wait for the brand icon to be designed rather than shipping with a generic substitute

Maintaining a consistent icon language across the site is more important than shipping fast with mismatched icons.

Was this page helpful?

We use this feedback to improve our documentation.

Thanks for your feedback