Spinner

Spinners serve as loading indicators, seamlessly integrating into your interface to provide a sleek visual cue during brief waiting periods. Use it to enhance user experience and maintain a polished design.

Example

Loading...

<div aria-live="polite" aria-atomic="true" class="nj-spinner">
  <p class="nj-sr-only">Loading...</p>
</div>

For accessibility purposes, we use the aria-live="polite" and aria-atomic="true" attributes and a nested hidden description.

  • aria-live="polite" and aria-atomic="true" ensure that screen readers announce updates when they occur and announce the entire content of the live region when it changes,
  • Screen readers will read the text provided in <span class="nj-sr-only">Loading...</span>.
<div aria-live="polite" aria-atomic="true" class="nj-spinner">
  <p class="nj-sr-only">Loading...</p>
</div>

Size variations

Spinner is large by default. Use the nj-spinner--{size} modifiers to adapt its size to fit your purpose. There are 5 available sizes:

  • lg: 64px (default)
  • md: 48px
  • sm: 32px
  • xs: 24px
  • xxs: 16px

Loading...

Loading...

Loading...

Loading...

Loading...

<!-- Large version by default -->
<div aria-live="polite" aria-atomic="true" class="nj-spinner">
  <p class="nj-sr-only">Loading...</p>
</div>

<div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--md">
  <p class="nj-sr-only">Loading...</p>
</div>

<div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--sm">
  <p class="nj-sr-only">Loading...</p>
</div>

<div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--xs">
  <p class="nj-sr-only">Loading...</p>
</div>

<div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--xxs">
  <p class="nj-sr-only">Loading...</p>
</div>

Inverse

Use the nj-spinner--inverse modifier.

Loading...

<div style="display: inline-block; padding: var(--nj-semantic-size-spacing-16); background: var(--nj-core-color-ultramarine-800); margin-right: var(--nj-semantic-size-spacing-32);">
  <div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--inverse">
    <p class="nj-sr-only">Loading...</p>
  </div>
</div>

Grey

Use the nj-spinner--grey modifier.

Loading...

<div aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--grey">
  <p class="nj-sr-only">Loading...</p>
</div>

With a label displayed

When you need to display a label, remove the .nj-sr-only element, add a label and position it using css. Here are two examples:

Loading

Loading

<div style="display: flex; align-items: start; gap: var(--nj-semantic-size-spacing-32);">
  <div style="display: flex; flex-direction: column; gap: var(--nj-semantic-size-spacing-8); align-items: center;">
    <div aria-live="polite" aria-atomic="true" class="nj-spinner"></div>
    <p>Loading</p>
  </div>
  <div style="display: flex; gap: var(--nj-semantic-size-spacing-8); align-items: center;">
    <div aria-live="polite" aria-atomic="true" class="nj-spinner"></div>
    <p style="margin-bottom: 0;">Loading</p>
  </div>
</div>

Within a Button

Use spinners within a disable button to indicate an action is currently processing or taking place and also preventing multiple clicks. To add a spinner inside a button, use the nj-spinner--xs size and make sure to use the correct spinner color variation. Here are some examples:

<button type="button" class="nj-btn" disabled>
  Submit
  <span aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--inverse nj-spinner--xs">
  <span class="nj-sr-only">Loading...</span>
</span>
</button>

<button type="button" class="nj-btn nj-btn--secondary" disabled>
  Submit
  <span aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--grey nj-spinner--xs">
  <span class="nj-sr-only">Loading...</span>
</span>
</button>

<button type="button" class="nj-btn nj-btn--subtle" disabled>
  Submit
  <span aria-live="polite" aria-atomic="true" class="nj-spinner nj-spinner--xs">
  <span class="nj-sr-only">Loading...</span>
</span>
</button>