Buy me a coffee

Theming

Every color, corner, space and animation comes from a token. Change a token and every component follows.

The tokens

Tokens are CSS custom properties that start with --dui-. After installing, they live in your own project, in src/lib/styles/distill-ui.

GroupExamplesFile
Colors--dui-color-background, --dui-color-primary, --dui-color-muted-foreground…themes/light.css and themes/dark.css
Corners--dui-radius (scales --dui-radius-sm to -xl)tokens.css
Spacing--dui-space-1 (0.25rem) to --dui-space-12 (3rem)tokens.css
Text--dui-font-sans, --dui-font-mono, --dui-text-xs to -lgtokens.css
Shadows--dui-shadow-xs to -lgtokens.css
Motion--dui-duration-fast|normal|slow, --dui-ease-*motion.css

The color names follow shadcn/ui: background and foreground for the page, primary for the main action, muted for quiet surfaces and text, destructive for danger, and so on.

Dark mode

Out of the box, the theme follows the visitor's system setting. To choose for them, set data-theme (or class="dark" / class="light") on the <html> element:

<!-- Follow the visitor's system setting (the default) -->
<html>

<!-- Always dark, or always light -->
<html data-theme="dark">
<html data-theme="light">

Components never check the theme themselves. They only read tokens, so a theme is just a different set of values.

Make it yours

The token files are yours to edit, the same as the components. To change the brand color, change it in both theme files, or let the theme builder write them for you:

src/lib/styles/distill-ui/themes/light.css
:root,
[data-theme='light'] {
	color-scheme: light;

	--dui-color-primary: oklch(0.55 0.2 260);
	--dui-color-primary-foreground: oklch(0.985 0 0);
	/* …the rest of the colors */
}

Corners and fonts are in tokens.css:

src/lib/styles/distill-ui/tokens.css
:root {
	/* One value scales every corner: 0 for square, 1rem for soft. */
	--dui-radius: 0.375rem;

	--dui-font-sans: 'Inter', system-ui, sans-serif;
}

Adding another theme

A theme is one selector with every color in it. Copy the colors from dark.css into a new file, change them, import the file after tokens.css, and set data-theme="ocean":

src/lib/styles/distill-ui/themes/ocean.css
[data-theme='ocean'] {
	color-scheme: dark;

	--dui-color-background: oklch(0.2 0.04 240);
	--dui-color-foreground: oklch(0.97 0.01 240);
	--dui-color-primary: oklch(0.75 0.12 200);
	--dui-color-primary-foreground: oklch(0.2 0.04 240);
	/* Copy every --dui-color-* from dark.css and change what you like. */
}

Reduced motion

When someone's system asks for reduced motion, every duration token becomes 0ms, so dialogs and menus appear without animating. You don't need to do anything for this.

Next: Theme builder →