Theming & Dark Mode
Focus UI includes built-in dark mode support with automatic system detection and manual control via JavaScript API.
How It Works
Focus UI supports three theme modes:
- Auto (default) - Follows system preference via
prefers-color-scheme - Light - Forces light mode regardless of system setting
- Dark - Forces dark mode regardless of system setting
Theme preference is persisted in localStorage and automatically restored on page load.
Theme Toggle Button
A ready-to-use toggle button that cycles through themes with appropriate icons.
<button class="focus-theme-toggle" onclick="FocusUI.Theme.toggle()">
<span class="focus-theme-toggle-icon">
<i class="focus-theme-icon-light fa fa-sun"></i>
<i class="focus-theme-icon-dark fa fa-moon"></i>
<i class="focus-theme-icon-auto fa fa-circle-half-stroke"></i>
</span>
<span class="focus-theme-toggle-label">Theme</span>
</button>
Compact Version
Icon-only toggle without label, ideal for navbars and toolbars.
<button class="focus-theme-toggle focus-theme-toggle-compact" onclick="FocusUI.Theme.toggle()">
<span class="focus-theme-toggle-icon">
<i class="focus-theme-icon-light fa fa-sun"></i>
<i class="focus-theme-icon-dark fa fa-moon"></i>
<i class="focus-theme-icon-auto fa fa-circle-half-stroke"></i>
</span>
</button>
In Navbar
The toggle automatically adapts styling when placed inside a navbar.
<nav class="focus-navbar">
<a href="#" class="focus-navbar-brand">My App</a>
<div class="focus-navbar-nav">
<a href="#" class="focus-navbar-link">Home</a>
<a href="#" class="focus-navbar-link">About</a>
</div>
<button class="focus-theme-toggle focus-theme-toggle-compact" onclick="FocusUI.Theme.toggle()">
<span class="focus-theme-toggle-icon">
<i class="focus-theme-icon-light fa fa-sun"></i>
<i class="focus-theme-icon-dark fa fa-moon"></i>
<i class="focus-theme-icon-auto fa fa-circle-half-stroke"></i>
</span>
</button>
</nav>
JavaScript API
For programmatic theme control, use the FocusUI.Theme service.
Get Current Theme
const theme = FocusUI.Theme.get()
const effective = FocusUI.Theme.getEffective()
Set Theme
FocusUI.Theme.set('dark')
FocusUI.Theme.set('light')
FocusUI.Theme.set('auto')
Toggle Theme
FocusUI.Theme.toggle()
Listen for Changes
document.addEventListener('focus-theme-change', (e) => {
console.log('Theme changed to:', e.detail.theme)
})
Methods
| Method | Returns | Description |
|---|---|---|
FocusUI.Theme.get() |
string | Current theme: 'light', 'dark', or 'auto' |
FocusUI.Theme.set(theme) |
void | Set theme to 'light', 'dark', or 'auto' |
FocusUI.Theme.toggle() |
void | Cycle: light → dark → auto → light |
FocusUI.Theme.getEffective() |
string | Actual theme: 'light' or 'dark' (resolves auto) |
FocusUI.Theme.init() |
void | Initialize theme (auto-called on page load) |
CSS Theming
By default, Focus UI uses CSS media queries for automatic dark mode. No JavaScript required.
@media (prefers-color-scheme: dark) {
:root {
--focus-color-bg: #111827;
--focus-color-text: #e5e7eb;
}
}
Custom Theme Styles
To add your own theme-specific styles:
[data-focus-theme="light"] .my-component {
background: white;
}
[data-focus-theme="dark"] .my-component {
background: #1f2937;
}
@media (prefers-color-scheme: dark) {
.my-component {
background: #1f2937;
}
}
Tip: When writing theme-aware CSS, handle both the [data-focus-theme] attribute (manual override) and the @media (prefers-color-scheme) query (auto mode) for complete coverage.
CSS Variables by Theme
These CSS custom properties automatically adapt based on the active theme:
| Variable | Light Mode | Dark Mode |
|---|---|---|
--focus-color-bg |
#ffffff | #111827 |
--focus-color-text |
#495057 | #e5e7eb |
--focus-color-text-muted |
#6c757d | #9ca3af |
--focus-color-surface |
#ffffff | #1f2937 |
--focus-color-card-bg |
#ffffff | #1f2937 |
--focus-color-border |
#ced4da | #374151 |
--focus-color-hover |
rgba(0,0,0,0.04) | rgba(255,255,255,0.08) |
See the Design System page for the complete list of CSS variables.
CSS Classes Reference
| Class | Description |
|---|---|
.focus-theme-toggle | Theme toggle button container |
.focus-theme-toggle-compact | Icon-only version (no label) |
.focus-theme-toggle-icon | Icon wrapper element |
.focus-theme-toggle-label | Text label (hidden in compact mode) |
.focus-theme-icon-light | Icon shown when theme is 'light' |
.focus-theme-icon-dark | Icon shown when theme is 'dark' |
.focus-theme-icon-auto | Icon shown when theme is 'auto' |