iconography
Icons are simple line drawings that sit next to words and help people find their way. Ours are small and drawn with a thin line, they take the colour of the text around them, and a screen reader skips them unless you give them a name.
the icon component
The icon component draws any icon from the set at the system's size and line weight, so icons look the same wherever they appear.
- It is 16 pixels by default, to match the interface text, with a line 1.75 wide. That is a little lighter than the icon set's own default.
- An icon takes the colour of the text around it. To tint an icon, tint the text it sits in.
- It is hidden from assistive technology unless you give it a name.
How it is built is on its React page.
where the icons come from
The icons come from an open-source set of line icons, which an app installs next to the design system as a peer dependency. The design system includes no icons of its own, so an app only carries the icons it actually uses.
Some components draw an icon themselves, such as the icon component and the tile: you tell them which icon. Others have a place for a finished icon, such as the start of a button or the inside of an icon button: you give them one drawn by the icon component. The specs show both in code.
sizes
| size | where |
|---|---|
| 12 | Inside small buttons and icon buttons; the size of their spinner |
| 16 | The usual size: next to interface text, inside medium buttons and icon buttons |
| 20 | Inside large icon buttons |
| 22 | A tile's app icon. The tile sets the size and the line itself; you only choose the icon |
The line stays 1.75 at every size. It is measured on the icon's own grid, so it gets thinner as the icon gets smaller: about 1.2 pixels at 16, and 1.6 at 22. Don't mix line weights on one screen.
colour
- Icons take the colour of the text around them: the body text's grey next to body text, the muted grey in a quiet label.
- Blue marks a destination: it is the colour of a tile's app icon.
- The signal colours belong to states, and a state needs words; see status. An icon on its own in green or red tells many people nothing.
decoration and meaning
- Next to words, an icon is decoration. The icon component hides it from assistive technology, and the words carry the meaning, in a button or in a tile.
- An icon that is a control's only content belongs in an icon button. The label it asks for becomes the button's name and its tooltip; leave the icon inside without a name.
- An icon that informs on its own is rare. Give it a name, and the icon component stops hiding it. Words next to it are still better.
- Never make a bare icon clickable. On its own, an icon can't take focus and doesn't say what it is, so people who use a keyboard or a screen reader can't use it.
shape
Icons are the only rounded shape in the system. The set draws them with round line ends and corners, and the app icons carry their rounded corners in the image itself. Everything around an icon stays square; see shape.
do and don't
related
- Icon button: an action that is only an icon, with the label it needs.
- Button: icons at the start and the end of a label.
- Tile: the app icon.
- Brand: the chevron and the lockup, which the library draws itself.
specs
| size | where |
|---|---|
| 12px | Inside sm (28px) buttons and icon buttons, the size of their spinner |
| 16px | The default: next to ui text, inside md (34px) buttons and icon buttons |
| 20px | Inside lg (42px) icon buttons |
| 22px | A tile's app icon, size and stroke set by Tile |
- The set. Line icons from Lucide. Install
lucide-react0.300.0 or later next to the library;reactandreact-dom18 or later are peers too. The library imports Lucide for its types only and bundles no icons: import each icon you use by name,import { Terminal } from 'lucide-react', and your bundle carries only those. Icon. Takes the Lucide component inicon(the component, not an element):<Icon icon={Terminal} />.sizeis the edge in px, 16 by default;strokeWidthis 1.75 by default (Lucide's own default is 2, at 24px). The stroke iscurrentColor. It is hidden from assistive tech unless you pass anaria-label, withrole="img".- Component or element.
Icon'siconandTile'sicontake the component. Slots take an element: a button'sleading={<Icon icon={Rocket} />}, or the icon as an icon button's child. - Stroke. 1.75 on Lucide's 24-unit grid: about 1.2px at 16px, 1.6px at 22px.
- Colour.
currentColor:--fg-2next to body text,--fg-mutedin a quiet label;--cloud-bluefor a tile's app icon. - Icon button. Its required
labelis the accessible name and the native tooltip. - Clickable. A bare
<svg>takes no focus and has no role.