Skip to content

Spinner

Add it to an element with aria-busy="true". Spinnners are always indeterminate.

html
<div aria-busy="true"></div>

Sizes

The spinner's size is set to 1em, which means it will adjust to its current font size.

h2

h4

Paragraph

SpanLink
html
<h2 aria-busy="true">h2</h2>
<h4 aria-busy="true">h4</h4>
<p aria-busy="true">Paragraph</p>
<span aria-busy="true">Span</span>

Buttons

Simply add aria-busy="true" to a <button>.

html
<!-- Text buttons -->
<button aria-busy="true" class="button">Text</button>
<button aria-busy="true" disabled class="button outlined">Outlined</button>
<button aria-busy="true" class="button filled">Filled</button>

<!-- Icon buttons -->
<button aria-busy="true" class="button">
  <span class="sr-only">Text</span>
</button>
<button aria-busy="true" disabled class="button outlined">
  <span class="sr-only">Outlined</span>
</button>
<button aria-busy="true" class="button filled">
  <span class="sr-only">Filled</span>
</button>

Linear progress

Check out the documentation for the progress bar.

When not to use aria-busy="true"

There are a few exceptions where aria-busy="true" won't render a spinner. Either because it doesn't make sense or because there are other reasons you would like to use that aria attribute.

Blocked by another use case

In conjunction with the <progress> element aria-busy="true" is used on the section that is being updated. Rendering a spinner here would result in a spinner and a progress bar which doesn't make sense.

See progress accessibility section for more.

Because it doesn't make sense

Installation

css
[aria-busy="true"]:not(
    input,
    select,
    textarea,
    html,
    progress,
    [aria-describedby]
  ) {
  position: relative;

  &:before {
    animation: spin 0.7s linear infinite;
    border-color: transparent currentColor currentColor;
    border-radius: 50%;
    border-style: solid;
    border-width: 3px;
    content: "";
    display: inline-block;
    block-size: 1em;
    opacity: 0.5;
    vertical-align: -0.14em;
    inline-size: 1em;
  }

  &:not(button.button):not(:empty) {
    &:before {
      margin-inline-end: 0.5em;
    }
  }
}

@keyframes spin {
  to {
    transform: rotate(1turn);
  }
}