Dark mode is currently in an experimental phase and is not guaranteed to meet DGA compliance standards. Use in production at your own discretion.
Button Toggle
An icon button that can be placed in any layout. Add data-theme-toggle to any button and it gets wired up automatically. The icon swaps between moon and sun to reflect the active theme.
<button class="nds-btn nds-subtle nds-icon-only"
data-theme-toggle aria-pressed="false" aria-label="Toggle dark mode">
<i class="nds-icon nds-hgi-moon-02" aria-hidden="true"></i>
</button>
Switch Toggle
A labeled switch for settings and preferences pages where users configure account options. Place data-theme-toggle on the switch container and the checkbox state stays in sync with the active theme.
<div class="nds-form-container nds-switch-container" data-theme-toggle>
<div class="nds-form-header" data-feedback-target>
<label for="darkmode-switch-1">
<span class="nds-label">Dark Mode</span>
<span class="nds-info">Switch between light and dark themes</span>
</label>
</div>
<div class="nds-form-control">
<div class="nds-switch nds-neutral">
<input type="checkbox" id="darkmode-switch-1" class="nds-switch-input" role="switch" aria-label="Dark mode">
<div class="nds-switch-track">
<div class="nds-switch-thumb"></div>
</div>
</div>
</div>
</div>
Built-in Features
Activates on page load and syncs all toggle elements to the stored theme without any configuration code.
Saves the chosen theme to localStorage under the key nds-theme so the preference survives page reloads and navigation.
Uses the View Transition API to expand the new theme outward from the toggle button in a circular ripple. Instant swap on browsers without support.
Any .nds-icon inside a toggle element switches between the sun and moon glyphs to reflect the active theme.
Every color is a semantic token. Custom dark overrides target :root[data-theme="dark"] in plain CSS, so they apply automatically when the theme switches.
Read or change the active theme from JavaScript at any time using NDS.Theme.get(), NDS.Theme.set(), and NDS.Theme.toggle().
Usage Guidelines
Best Practices
- Place the button toggle in the Top Bar so it is reachable from every page without scrolling
- Use the switch toggle in settings or preferences pages alongside other binary options such as notifications and language selection
- Add
data-theme-toggleto one top-level element per toggle control. Do not nest two elements with that attribute inside each other - Do not wire up a custom click handler to control the theme. Use
NDS.Theme.set()when you need programmatic control instead - Always include
aria-labelon a button toggle and a linked<label>on a switch toggle so screen reader users understand the control - Write dark overrides using
:root[data-theme="dark"] .your-selector { ... }in your stylesheet. Keep them next to the base styles for the same element so they are easy to find and update - Always reference semantic tokens (e.g.
--background-card,--text-default) in component styles. Components that use hardcoded colors will not respond to the theme toggle - Test both themes whenever you add a new component or page surface. Dark mode is fully supported in the design system and components are expected to look correct in both states
Data Attributes
| Attribute | Description |
|---|---|
data-theme-toggle | Place on any button or switch container to register it as a theme toggle. The JS binds the click handler and keeps aria-pressed, icon classes, and checkbox state in sync automatically. |
Adding Dark Overrides
Scope any custom styles to dark mode using the :root[data-theme="dark"] selector in plain CSS.
.my-component {
background: var(--background-card);
color: var(--text-default);
}
:root[data-theme="dark"] .my-component {
background: var(--colors-neutral-800);
}
JavaScript API
The NDS.Theme module initializes automatically on page load. Use the public API to read or change the theme from your own scripts.