Theming

Lily components cairry stable class hooks an zero CSS — sae a theme is juist a stylesheet. This tutorial gangs frae “link ae file” tae “let the uiser switch themes at runtime, persistit”.

Whit ye'll big

An app whase entire look the uiser can chynge — stairtin wi ae linkit stylesheet, endin wi a persistit runtime theme switcher — in aboot 15 minutes.

Afore ye stairt

Feenish the framework tutorial first for yer stack, sae ye hae a wee Lily form tae theme. Aathing here wirks in aw seiven frameworks; code samples shaw Svelte an plain HTML.

Step 1 — Link a ready-made theme

The themes/ directory ships 45 standalane stylesheets. Copy them intae yer app's static assets an link ane:

<link rel="stylesheet" href="/assets/themes/united-kingdom-national-health-service-england-for-patients.css" />

Highlichts o the set:

  • Public sector — NHS England / Scotland / Wales, ilkane in patient-facin an practitioner-facin variants; GOV.UK (united-kingdom-government-digital-service); USWDS (united-states-web-design-system).
  • Vendor-inspired — adobe-spectrum, mozilla-protocol.
  • General purpose — light, dark, nord, dracula, wireframe, corporate, synthwave, an mony mair.

Check yer wirk: reload the page. The same markup ye biggit in the framework tutorial is noo fully styled — buttons, inputs, labels, focus rings. Ae line o HTML did that — ilka component bade exactly as it wis.

Step 2 — Owerride onything

Theme selectors are wrappit in :where(...), which haes zero specificity — sae onie rule ye write wins, plain an simple:

/* After the theme link: your brand button, everything else themed */
.button {
  background: #7c3aed;
  border-radius: 9999px;
}

Step 3 — Runtime switchin wi theme-picker

The theme-picker helper is a headless icon-button + listbox that owns the hail theme lifecycle: it loads the chosen stylesheet bi swappin ae managed <link> (anely the active theme is ever fetched), sets data-theme="{slug}" on the document, an optionally persists tae localStorage. Svelte shawn here; React, Vue, Angular, HTML, Nunjucks, an Blazor ports match contract-for-contract:

<script>
  import ThemePicker from "@lilydesignsystem/svelte-theme-picker";
</script>

<ThemePicker
  label="Theme"
  themesUrl="/assets/themes/"
  themes={["light", "dark", "nord", "wireframe"]}
  storageKey="my-app-theme"
/>

That's the hail integration. Keyboard behaviour follaes the WAI-ARIA APG listbox pattern; the control itsel is headless (class hook .theme-picker), sae it picks up whitever theme is active.

Verified 2026-08-29: this exact snippet wis compilit against the publishit 0.1.1 package through svelte/server.

Step 4 — React tae the theme in yer ain CSS

Because the helper sets data-theme on the document root, yer ain styles can branch on it:

[data-theme="dark"] .site-logo { filter: invert(1); }

Notes for server renderin

The helper performs aw DOM writes inside the framework's mount/effect lifecycle, sae it is SSR-safe bi construction. Tae avoid a first-paint flash, render the initial theme's <link> an data-theme on the server (for example frae a cookie) — the Svelte helper repo ships a runnable SvelteKit cookie example, an the ither catalogs document the same pattern for their stacks.

Neist steps

  • Preference helpers — the same pattern for leid, text size, sharin, an date/time entry.
  • Contribute a theme — ilkane is ae standalane stylesheet targetin the class hooks; see contributin.

Questions alang the wey? The help page is fu o answers — an if a step could be clearer, tell us an we'll gladly improve the tutorial.