A theme you can switch with one attribute

Build a light and dark theme, and a spacing scale, from variables.

What to build

A themed page, currently set to dark.

Requirements

  • :root defines --bg: white, --text: #222222 and --space: 8px.
  • [data-theme="dark"] changes --bg to #111111 and --text to #eeeeee.
  • body uses both colour variables.
  • The html element has data-theme="dark".
  • .box has a padding of var(--space) multiplied by 3, written with calc().
  • A media query for prefers-color-scheme: dark exists and also sets --bg to #111111.

Constraints

No colours may be set directly on body or .box.

Example

margin: calc(var(--space) * 2);

Why it works

The theme only replaces the values of variables, so no individual rule has to know which theme is active.

Hints

Hint 1

The dark theme only changes variables.

Hint 2

Set the attribute in the HTML, on the html element.

Hint 3

calc can multiply a variable.

Solution

Show one correct solution (try it yourself first)
<!doctype html>
<html lang="en" data-theme="dark">
<head>
  <meta charset="utf-8">
  <title>Theme</title>
  <style>
    :root { --bg: white; --text: #222222; --space: 8px; }
    [data-theme="dark"] { --bg: #111111; --text: #eeeeee; }
    @media (prefers-color-scheme: dark) {
      :root { --bg: #111111; --text: #eeeeee; }
    }
    body { background: var(--bg); color: var(--text); }
    .box { padding: calc(var(--space) * 3); }
  </style>
</head>
<body>
  <div class="box">Hello</div>
</body>
</html>

Lesson: Custom properties (CSS variables) →