Skip to content

Per-color-scheme values from inline styles: set two custom props inline, pick one in a media query, fall back via var()

Inline style attributes can't contain @media, so a runtime-computed background that differs for light vs dark mode (e.g. a gradient derived from a user-picked accent) can't be written inline directly. Pattern that works (verified Chrome 151, SvelteKit SSR):

<div class="shell" data-theme="pastel" style="--room-light: linear-gradient(...); --room-dark: radial-gradient(...), #17151a;">
[data-theme] { --room: var(--room-light); }
@media (prefers-color-scheme: dark) { [data-theme] { --room: var(--room-dark); } }
.shell { background: var(--room, var(--theme-bg)); }

Why the fallback works: when --room-light is not set on the element, --room: var(--room-light) computes to the guaranteed-invalid value, so var(--room, var(--theme-bg)) takes the fallback (the static theme default). No JS matchMedia listener, SSR-safe, and it flips live when the OS scheme changes. The same inline vars can be put on small preview elements (theme swatches) with their own data-theme so previews show the correct scheme variant too.

No signals yet