Skip to content

Spinner

A ring that spins while something loads. If you know how long it takes, or how far it has got, Progress is better. This one only says that something is in progress.

data-sizeUsed for
smallInside a button or a table row
(omitted)Next to a text
largeIn the middle of a page or in a panel that is loading

Someone listening to the page gets nothing from a ring. Let a visible text carry the message. The ring can get a name with aria-label, but it is not certain to be announced by itself; see below.

If the text is visible, set aria-hidden="true" on the ring. If the ring also has a name, the wait is otherwise announced twice.

The paragraph is announced when the text is inserted into it. So leave <p role="status"> empty in the page beforehand, and write the ring and the text into it when the wait begins.

The ring is inline-block, so it sits in line with the text by itself. If you want them on the same baseline with a fixed gap, that is the app’s layout: display: flex, align-items: center and gap on the paragraph.

If the ring stands alone, it gets the role and the name itself:

<span class="lt-spinner" role="status" aria-label="Loading applications"></span>

That gives the ring a name when someone looks for it, but it is not certain to be announced by itself. A region with role="status" announces changes to its content, and the ring has no content. If it matters that the wait is reported, use the paragraph with text above, in a status element that is in the page before the wait starts.

<button class="lt-button" disabled>
<span class="lt-spinner" data-size="small" aria-hidden="true"></span>
Sending application
</button>

Let the button text change from “Send application” to “Sending application”. Then the button says what is happening, also for someone who does not see the ring.

ClassWhat it is
.lt-spinnerThe ring. The size comes from data-size.
VariableDefault
--lt-spinner-sizevar(--lt-spacing-6)
--lt-spinner-thickness2px

The variables apply to the default size. data-size="small" and data-size="large" set their own size, and large its own thickness as well.

If the user has asked for reduced motion in their system, the ring spins more slowly. It does not stop completely: an indicator that stands still no longer says that something is in progress.

See Customising for how the variables and the layer work.

  • Wait a little before you show it. A ring that flashes past in 100 milliseconds is more disturbing than nothing.
  • Say what is loading, not just that something is loading. “Fetching your applications” is worth more than “Loading”.
  • When the wait is over, move focus to where the result appeared, or report it in a role="status" element. Otherwise the user is left without knowing that anything happened.