Skip to the page
TACTILE UI

Kit part · Icons

Icons

The kit’s glyphs as one set: drawn on a 16 grid with a 1.6 line, round ends, in currentColor, so an icon prints in whatever ink it sits in, in either finish.

Element
<svg>
Needs
kit.css + kit.mjs
Rules
icons.rules.md · 5
Finishes
Aluminium · Graphite · Porcelain · Black
Volumes
Tactile · Quiet
On this page
  1. Variants
  2. Every state, at once
  3. API
  4. Markup
  5. Accessibility
  6. How it’s built
  7. Rules
  8. Related parts
01

Variants

Sizes · 12 · 16 · 20 · 24
Saved to the hubReserve is low
Beside words
In a key
Alone · role="img"
In ink · never tinted
3 unread
A lamp says on
02

Every state, at once

Both finishes, side by side. Hover, pressed and focus are forced with .is-hover, .is-down and .is-focus; checked and disabled are real.

Aluminium

PartRestHoverPressedFocus
Grid cell

Graphite

PartRestHoverPressedFocus
Grid cell
03

API

NameKindValuesWhat it does
.tui-iconclasson <svg>A 16px box, inline, aligned to the text’s lower line; color inherits, so the icon takes the ink it stands in.
--sm · --lg · --xlclass12 · 20 · 24 pxSizes. The line scales with the box and stays a tenth of it.
viewBox="0 0 16 16"attributethe gridEvery glyph is drawn inside a 2 unit margin, so a set of them is optically level.
fill="none" stroke="currentColor" stroke-width="1.6"attributeon the <svg>The line: 1.6 on the 16 grid, round caps and joins. A dot is the only filled mark.
aria-hidden="true" · role="img" aria-labelattribute—Hidden when beside words; an image with a name when the glyph is the whole message.
icon(name, { size, label, cls })functionkit.mjsThe <svg> for one glyph. Decorative unless a label is given. An unknown name returns an empty string.
ICONS · ICON_NAMESobject · arraykit.mjsThe set: each name to the inside of its <svg>. 42 glyphs.
.tui-icon-grid · __cellclass—The set laid out as printed cells, a glyph above its name. Cells are keys: press to copy.
data-sizeattribute"12" · "16" · "20" · "24"On a grid: scales every glyph in it.
04

Markup

<!-- Beside words: decorative, so it is hidden from screen readers -->
<button class="tui-key">
  <svg class="tui-icon" viewBox="0 0 16 16" fill="none" stroke="currentColor"
       stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
    <circle cx="7" cy="7" r="4.2"/><path d="m10.2 10.2 3.3 3.3"/>
  </svg>
  Search
</button>

<!-- Alone, carrying the meaning: an image with a name -->
<svg class="tui-icon" viewBox="0 0 16 16" … role="img" aria-label="Warning">…</svg>

<!-- In an icon key: the button is named, the glyph is not -->
<button class="tui-key tui-key--icon" aria-label="Copy" data-tip="Copy">…</button>
import { icon, ICONS, ICON_NAMES } from '/kit/kit.mjs';

button.insertAdjacentHTML('afterbegin', icon('search'));            // aria-hidden
link.insertAdjacentHTML('beforeend', icon('external', { size: 'sm' }));
status.innerHTML = icon('warning', { label: 'Warning' });           // role="img"

ICON_NAMES.length;   // 42
ICONS.check;         // '<path d="m3.5 8.6 3 3 6-6.6"/>'  the inside of the <svg>

Needs kit.css and kit.mjs. How to install the kit.

05

Accessibility

  • An icon beside words is decoration: aria-hidden="true", so the words are read once. An icon that stands alone is role="img" with a label that says what it means, not what it looks like.
  • On an icon key it is the button that is named (aria-label), and the glyph stays hidden.
  • An icon never carries state by tint: a lit lamp beside it, or a word, says “on”, “unread” or “failed”.
  • A glyph inherits the ink of its parent, so it keeps the text’s contrast in both finishes and follows the disabled 45%.
  • The grid’s cells are real buttons with a name (“Copy search”); the glyph in each is hidden.
06

How it’s built

Every glyph is a few strokes on a 16 × 16 grid with a 2 unit margin, drawn with one line weight (1.6), round ends and joins, and no fill except a dot. The set is data, not sprites: ICONS maps a name to the inside of the SVG and icon() wraps it in the same attributes every time, which is what keeps a page of them level. The sidebar’s category glyphs are the same hand on a 20 grid with a 1.5 line (97 of them, from app/icons.mjs), shown here beneath the interface set.

07

Rules

icons.rules.mdIn the brain

One hand, one line weight, no colour: an icon is beside words or in a key, and it is named where it stands alone.

5 rules in this file, with the foundations they rest on and the anti-patterns that break them. Full rules ship in the brain with the Pass.

08

Icon key

A key with an icon and no words, square or round: transport, power, the small tools. Its aria-label names it; a tip shows the name.

Key

Every button, and every link that acts like one: a cap on a skirt that drops below the plate when pressed.

Lamp

The only colour in the kit: a lamp that is on. Green is on, amber is waiting, red is recording or failing, blue is linked, white is standing by. Always next to words.

Docs
Finish
Volume