tezvyn:

Light and dark themes with design tokens

AI-drafted, machine-checkedSource: interviewintermediate
WHAT IT TESTS

token file structure for two themes.

OUTLINE

a shared primitives file plus per-theme semantic files, transformed into custom properties scoped by selector, components read the semantics.

RED FLAG

duplicated stylesheets or hardcoding.

WHAT THIS TESTS Whether you can translate the token concept into a concrete file layout and the actual CSS that enables runtime theme switching.

A GOOD ANSWER COVERS Structure the source in layers. One primitives file holds raw values, like color palette steps. Then two semantic files, one for light and one for dark, each defining the same semantic names, such as color-bg, color-surface, color-text, but pointing at different primitives appropriate to that theme. A build tool transforms these into CSS. The output is CSS custom properties: the light semantics are written under :root as the default, and the dark semantics are written under a selector like html[data-theme=dark] or a prefers-color-scheme media query. Components never branch on theme; they simply use var(--color-bg) and friends. Switching themes means setting the data-theme attribute, and the cascade resolves each property to the active theme's value.

COMMON WRONG ANSWERS Producing two complete component stylesheets, one per theme, duplicates everything and breaks runtime switching. Hardcoding hex values per theme in components defeats tokens. Forgetting a default in :root leaves unthemed states broken. Using only Sass variables makes switching require a recompile.

LIKELY FOLLOW-UPS How do you respect the OS preference? Add a prefers-color-scheme block. How do you prevent a flash of light theme? Set data-theme via an inline script before paint. Where do shared, non-theme values live? In primitives or theme-agnostic tokens.

ONE CONCRETE EXAMPLE The primitives file defines gray-50 through gray-900. The light semantic file sets color-bg to gray-50 and color-text to gray-900; the dark file sets color-bg to gray-900 and color-text to gray-50. The transformer emits these as custom properties under :root and under html[data-theme=dark]. A page section using background var(--color-bg) flips instantly when the attribute changes, with one shared stylesheet. An inline script sets data-theme before the stylesheet loads so there is no flash of the wrong theme on first paint.

Read the original → designtokens.org

Get five bites like this every day.

Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.