Loading Spinner
Add data-state="loading" or .nds-loading to any container to dim its content and show a centered spinner
Content is dimmed while loading
<div data-state="loading">
<p>Content is dimmed while loading</p>
</div>
<!-- Or use class toggle -->
<div class="nds-loading">
<p>Content is dimmed while loading</p>
</div>
Content is dimmed while loading
<div class="nds-loading nds-oncolor">
Content hidden while loading
</div>
Neutral
Black spinner on light backgrounds, automatically inverts to white in dark mode
Content is dimmed while loading
<div class="nds-loading nds-neutral">
<p>Content is dimmed while loading</p>
</div>
Size Variants
Loading spinners are available in 7 sizes: xxs (20px), xs (24px), sm (28px), md (32px default), lg (36px), xl (40px), 2xl (44px)
<div class="nds-loading nds-xxs">...</div> <!-- 20px -->
<div class="nds-loading nds-xs">...</div> <!-- 24px -->
<div class="nds-loading nds-sm">...</div> <!-- 28px -->
<div class="nds-loading">...</div> <!-- 32px (default) -->
<div class="nds-loading nds-lg">...</div> <!-- 36px -->
<div class="nds-loading nds-xl">...</div> <!-- 40px -->
<div class="nds-loading nds-2xl">...</div> <!-- 44px -->
Built-in Features
No JavaScript required. Add the class or attribute and the spinner renders immediately via CSS ::after.
The default spinner inverts to white in dark mode. nds-neutral follows the same inversion automatically.
pointer-events: none is applied to the loading container, preventing clicks on dimmed content.
On skeleton-capable elements (grids, cards, accordions, tabs, tables), the spinner is suppressed and child opacity is restored so the skeleton provides the feedback.
Usage Guidelines
Best Practices
- Prefer
data-state="loading"for JS-toggled states; prefer thends-loadingclass when the state is server-rendered or set via a simple class toggle - Add
nds-neutralwhen the spinner appears over a white or light-tinted surface where the default primary-colored spinner would clash - Add
nds-oncolorwhen the container background is always dark (for example, a primary-colored banner); this forces the spinner white regardless of color scheme - Do not add
nds-loadingdirectly to.nds-btn: buttons handle their own loading state and the child-dim rule is already excluded for them - On skeleton-capable elements (
.nds-grid,.nds-card,.nds-accordion,.nds-tabs,tbody), the skeleton IS the visual feedback; the spinner is automatically suppressed by CSS and you do not need to handle it separately - Size the spinner to match the container: use
nds-xxsornds-xsinside compact components (table cells, small cards) andnds-xlornds-2xlfor full-page overlays
Modifier Classes
| Class | Description |
|---|---|
nds-neutral | Black spinner on light backgrounds; inverts to white in dark mode |
nds-oncolor | Forces a white spinner regardless of color scheme, for use on always-dark backgrounds |
nds-xxs | Spinner 20px, border 2px |
nds-xs | Spinner 24px, border 2px |
nds-sm | Spinner 28px, border 2px |
nds-md | Spinner 32px, border 3px (same as the default) |
nds-lg | Spinner 36px, border 3px |
nds-xl | Spinner 40px, border 4px |
nds-2xl | Spinner 44px, border 4px |
Data Attributes
| Attribute | Description |
|---|---|
data-state="loading" | Alternate trigger for the loading state. Equivalent to the nds-loading class; useful when a component already manages data-state for other states |
CSS Custom Properties
| Property | Default | Description |
|---|---|---|
--loading-color | --background-primary (white in dark) | Spinner arc color |
--loading-track | --colors-alpha-black-10 (colors-alpha-white-20 in dark) | Spinner track (background ring) color |
--loading-size | 32px | Diameter of the spinner |
--loading-border | 3px | Stroke width of the spinner ring |
--loading-opacity | 0.15 | Opacity applied to child elements while loading |
Skeleton Processing State
When nds-loading or data-state="loading" is applied to the following elements, the spinner (::after) is suppressed and child opacity is restored to 1. The skeleton styling defined in each component provides the visual feedback instead. pointer-events: none still applies.
| Element | Notes |
|---|---|
.nds-grid | Card grids in a loading state show skeleton cards |
.nds-paged-content | Paginated content region; skeleton suppresses spinner during page turns |
tbody, .nds-table | Table body and table wrapper; skeleton rows replace the spinner |
.nds-accordion | Accordion panels show skeleton items |
.nds-tabs, .nds-tab-list | Tab strip and tab panels |
.nds-card | Individual card in a loading state shows a skeleton body |
.nds-definition-list | Definition list |
.nds-stepper | Stepper component |
.nds-breadcrumb-nav | Breadcrumb navigation |