Theming
Staticview components are styled through CSS custom properties (--sv-* tokens). Custom properties inherit, so you can define the tokens once on :root, or override any of them on a specific container to theme just a part of the page.
Without a theme, components fall back to the browser’s system colors (AccentColor, ButtonBorder, …), so they stay usable. Importing or defining a theme is still recommended.
Default Theme
The library ships an adaptive theme that supports both light and dark modes. It is not applied automatically, so import it explicitly before using any components.
@import "@staticview/ui/themes/default.css";Light & Dark Mode
The default theme resolves its colors with the CSS light-dark() function, which follows the page’s color-scheme. Declare a color scheme in your stylesheet, otherwise every token resolves to its light value:
:root { /* Follow the user's OS/browser preference */ color-scheme: light dark;}Use color-scheme: light or color-scheme: dark to force a single mode. Since color-scheme applies per element, you can also flip it for one section of the page only.
Changing the Hue
The default theme derives its grayscale and accent color from two hue tokens. Overriding them re-tints the entire theme without touching any other variable:
:root { --sv-hue-accent: 260; /* Hue of the accent color (OKLCH hue, 0–360) */ --sv-hue-base: 240; /* Subtle tint applied to the grayscale */}Token Reference
--sv-gray-0…--sv-gray-7: grayscale ramp.0is the highest-contrast content color (text, icons) and7is the base surface color. The default theme flips the ramp automatically between light and dark mode.--sv-accent: brand/accent color used for primary actions and highlights.--sv-accent-content: content color (text, icons) rendered on top of the accent color.--sv-info,--sv-success,--sv-warning,--sv-error: status colors used by alerts and validation states.--sv-overlay: translucent backdrop behind dialogs and flyouts.--sv-bdr-sz-sm/md/lg: border widths.--sv-bdr-rad-sm/md/lg: border radii.--sv-dir: text direction multiplier for directional offsets,1= LTR and-1= RTL. See RTL Support.
For reference, the full default theme:
:root { /* Hue */ --sv-hue-accent: 85; --sv-hue-base: 305;
/* Grayscale */ --sv-gray-0: light-dark(oklch(30% 0.034 var(--sv-hue-base)), oklch(90% 0.017 var(--sv-hue-base))); --sv-gray-1: light-dark(oklch(36% 0.038 var(--sv-hue-base)), oklch(80% 0.03 var(--sv-hue-base))); --sv-gray-2: light-dark(oklch(36% 0.038 var(--sv-hue-base)), oklch(80% 0.03 var(--sv-hue-base))); --sv-gray-3: light-dark(oklch(44% 0.034 var(--sv-hue-base)), oklch(65% 0.028 var(--sv-hue-base))); --sv-gray-4: light-dark(oklch(66% 0.03 var(--sv-hue-base)), oklch(48% 0.024 var(--sv-hue-base))); --sv-gray-5: light-dark(oklch(88% 0.023 var(--sv-hue-base)), oklch(29% 0.02 var(--sv-hue-base))); --sv-gray-6: light-dark(oklch(93% 0.017 var(--sv-hue-base)), oklch(23% 0.017 var(--sv-hue-base))); --sv-gray-7: light-dark(oklch(96% 0.012 var(--sv-hue-base)), oklch(20.5% 0.014 var(--sv-hue-base)));
/* --- Main Brand Colors --- */ --sv-accent: light-dark(oklch(53% 0.1197 var(--sv-hue-accent)), oklch(63% 0.105 var(--sv-hue-accent))); --sv-accent-content: light-dark(var(--sv-gray-7), var(--sv-gray-0));
/* --- Status/Semantic Colors --- */ --sv-info: light-dark(#252e8a, #c5cff5); --sv-success: light-dark(#1a5e55, #c7eae2); --sv-warning: light-dark(#6b4800, #f8e2b6); --sv-error: light-dark(#7b1a2e, #f3c8cb);
/* --- Overlay/Backdrop Color --- */ --sv-overlay: #000000a0;
/* --- Size Variables (Borders & Radius) --- */ --sv-bdr-sz-sm: 1px; --sv-bdr-sz-md: 2px; --sv-bdr-sz-lg: 4px; --sv-bdr-rad-sm: 4px; --sv-bdr-rad-md: 8px; --sv-bdr-rad-lg: 16px;
/* --- Direction Variables: 1 = LTR, -1 = RTL --- */ --sv-dir: 1;}
[dir="rtl"] { --sv-dir: -1;}Custom Theme
Override Specific Tokens
The most common approach: import the default theme and override only what you need.
@import "@staticview/ui/themes/default.css";
:root { --sv-accent: light-dark(#4c5fa8, #7c8fd1); --sv-bdr-rad-md: 12px;}Build a Theme from Scratch
Skip the default import and define the tokens directly in your stylesheet.
:root { --sv-gray-0: #f5f5f5; --sv-gray-1: #d4d4d4; --sv-gray-2: #a3a3a3; --sv-gray-3: #737373; --sv-gray-4: #525252; --sv-gray-5: #404040; --sv-gray-6: #262626; --sv-gray-7: #171717; --sv-accent: #7c8fd1; --sv-accent-content: #0f1117; --sv-info: #7fb8db; --sv-success: #8ec97f; --sv-warning: #f5d76e; --sv-error: #e87d7a; --sv-overlay: #000000a0; --sv-bdr-sz-sm: 1px; --sv-bdr-sz-md: 2px; --sv-bdr-sz-lg: 4px; --sv-bdr-rad-sm: 4px; --sv-bdr-rad-md: 8px; --sv-bdr-rad-lg: 16px; --sv-dir: 1;}
[dir="rtl"] { --sv-dir: -1;}Note
Any color token you leave undefined falls back to the browser’s system colors, which likely won’t match your palette, so define all of them. Plain color values like the ones above produce a single-mode theme; wrap each pair in light-dark() (as the default theme does) to support both light and dark mode.
Map to an Existing Design System
If your project already has design tokens, map them to the Staticview tokens instead of duplicating values:
@import "@staticview/ui/themes/default.css";
:root { --sv-gray-0: var(--sb-color-gray-0); --sv-gray-1: var(--sb-color-gray-1); --sv-gray-2: var(--sb-color-gray-2); --sv-gray-3: var(--sb-color-gray-3); --sv-gray-4: var(--sb-color-gray-4); --sv-gray-5: var(--sb-color-gray-5); --sv-gray-6: var(--sb-color-gray-6); --sv-gray-7: var(--sb-color-gray-7); --sv-accent: var(--sb-color-accent); --sv-info: var(--sb-note-text); --sv-success: var(--sb-tip-text); --sv-warning: var(--sb-warning-text); --sv-error: var(--sb-caution-text);}Keeping the default import means sizes, radii, and any color you don’t map keep their default values.
Scoped Themes
Tokens don’t have to live on :root. Override them on any element to re-theme everything inside it. This is useful for embedding components in an area with different branding:
.marketing-panel { --sv-accent: oklch(60% 0.15 300); --sv-bdr-rad-md: 16px;}RTL Support
Directional offsets inside components are multiplied by --sv-dir. The default theme sets it automatically based on the document’s dir attribute:
:root { --sv-dir: 1; /* LTR */}
[dir="rtl"] { --sv-dir: -1; /* RTL */}If you build a theme from scratch, keep this rule so components render correctly in RTL layouts.