Skip to the page
Tactile UI

Kit part · Loaders

Spinner

A ring of eight lamps lit in turn, a chase round a dial: each lamp is a dim cap with its light laid over it, and the light fades as the chase passes on, leaving a short tail. Only the light’s opacity moves. Amber, the lamp for work in hand. Under reduced motion it holds still on one lit lamp at the top, and the words still say it is busy.

Element
<span class="tui-spinner" role="status">
Needs
kit.css + kit.mjs
Rules
spinner.rules.md · 6
Finishes
Aluminium · Graphite · Oak · Walnut · Porcelain · Black · Daylight · Night · Paper · Phosphor · E-paper · AMOLED
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

Seats open in 11 days. Want one email that morning?

Variants

Loading
Default · 24px
Loading
Small · --sm
Loading
Large · --lg
Searching the archive
With words on screen · --labelled
Working (green)Working (red)Working (blue)Working (white)
Lamp colours · data-lamp
In a key

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

PartSmallDefaultLargeLabelledGreen
SpinnerLoadingLoadingLoadingLoadingDone soon

Graphite

PartSmallDefaultLargeLabelledGreen
SpinnerLoadingLoadingLoadingLoadingDone soon

API

NameKindValuesWhat it does
span.tui-spinner[role="status"]elementwith a labelThe spinner. A status region, so its label is said when it appears. Add data-lamp to light the ring green, red, blue or white (amber is the default).
.tui-spinner__ring[aria-hidden="true"]elementeight <i>The drawing: eight empty i elements, one lamp each. Hidden from a screen reader.
.tui-spinner__labelelementthe wordsWhat is going on. Always in the page for a screen reader; drawn on screen with --labelled.
--sm · --lg · --labelledmodifier16px · 40px · words shownThe ring’s size, and whether the label is drawn beside it. Set --sp for any other size.
spinnerHTML({ label, size, lamp, labelled, status })functionpureThe markup of one. Pass status: false inside a region that is already a status.
data-pausedattributeset by kit.mjsHolds the chase while the spinner is off screen. Set it yourself in a hidden pane.

Markup

<span class="tui-spinner tui-spinner--labelled" role="status">
  <span class="tui-spinner__ring" aria-hidden="true">
    <i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i>
  </span>
  <span class="tui-spinner__label">Importing 3 of 14 files</span>
</span>

<!-- Without the words on screen, they are still said: drop --labelled -->
import { spinnerHTML } from '/kit/kit.mjs';

// The markup of one, so a script does not have to type eight <i>.
el.innerHTML = spinnerHTML({ label: 'Importing', size: 'lg', labelled: true });
spinnerHTML({ label: 'Saving', status: false });     // inside a region that already says it

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

Accessibility

  • It is role="status" with its words in .tui-spinner__label, so a screen reader says “Importing 3 of 14 files” politely when it appears; the eight lamps are aria-hidden.
  • Busy is said in words and shown by the chase, never by colour alone, and the words are what to put on screen when the wait may be long.
  • Under reduced motion the chase stops and the lamp at the top stays lit, so it is a steady lamp that still says busy. Nothing else moves, and it never speeds up or bounces.
  • The chase runs a second at a time and is the sign that something is loading, not decoration; it pauses while it is off screen, and it should be taken out of the page the moment the work ends.
  • It is not a control: it takes no focus and no pointer, and on a phone it is the same size.

How it’s built

Eight lamps on a circle, each a dim cap with a lit layer on top of it. Every lit layer runs the same short fade, 960 milliseconds long, started a step later than its neighbour, so the lit one appears to travel and the lamps just behind it are still dying away. The lamps are placed with a direction and a radius rather than rotated, so each one’s shine stays on its upper left. In the finishes that draw their lamps as square pixels or printed rings, the spinner’s lamps are drawn the same way.

Rules

spinner.rules.mdIn the brain

Show that something is working when no one can say how long it will take: a ring of lamps chased in turn, with a line of words that is the real message.

6 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.

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.

Skeleton

The shape of a page before its data arrives, drawn as the unprinted plate: blank engraved bars where the words will print. Nothing on it moves. One amber lamp beside “Loading” is the only sign of work.

Progress

Progress through a task: ink filling a groove, never a coloured bar.

Invoice 0412 · NorthwindDraft
Saving

Loading overlay

A pane of smoked glass laid over a panel while it works. The panel underneath keeps every pixel of its place, dimmed and a little out of focus, with one plate in the middle carrying a spinner and a line of words. Set aria-busy on the panel to lower the glass; what is underneath goes inert, so nothing in it can be pressed or tabbed to until the glass lifts.