Back to Curriculum

CSS Custom Properties and Theming

📚 Lesson 15 of 16 ⏱️ 40 min

CSS Custom Properties and Theming

40 min

We touched on variables earlier, but their true power shines in **Theming**. Because CSS variables are live and inherit, you can swap entire color palettes by changing a class on the `<body>` or `<html>` tag.

This is how Dark Mode works. You define your colors as variables (e.g., `--bg-color`, `--text-color`). Then, inside a media query `@media (prefers-color-scheme: dark)` or a class `.dark-theme`, you simply update the values of those variables. The entire site updates instantly.

You can also use JavaScript to set variables based on user interaction (like a color picker) or mouse position, enabling dynamic effects that were previously impossible with CSS alone.

Scope is important. You can define variables locally within a component to create isolated themes or 'skins' for specific widgets.

Key Concepts

  • Variables enable global theming.
  • Dark Mode via `prefers-color-scheme`.
  • Class-based theming (e.g., `.dark`).
  • JS interaction with `setProperty`.
  • Scoped variables for component isolation.

Learning Objectives

Master

  • Building a complete Dark Mode system
  • Structuring CSS for theming
  • Manipulating variables with JavaScript
  • Handling system preferences

Develop

  • User experience customization
  • Scalable design systems
  • Accessibility (high contrast modes)

Tips

  • Define all theme colors in a separate `:root` block.
  • Use HSL colors for easier programmatic manipulation.
  • Store the user's theme preference in `localStorage`.
  • Use `transition: background-color 0.3s` for smooth theme switching.

Common Pitfalls

  • Hardcoding colors instead of using the variables.
  • Forgetting to update images or icons for dark mode (they might disappear).
  • Flash of unstyled content (FOUC) when loading themes via JS.
  • Not checking contrast ratios in both light and dark modes.

Summary

  • Theming is easy with CSS variables.
  • Dark mode is a standard requirement now.
  • Variables bridge the gap between CSS and JS.
  • They enable scalable, maintainable design systems.

Exercise

Create a theme system with light and dark mode using CSS variables.

:root {
  --bg-color: #ffffff;
  --text-color: #333333;
}

[data-theme="dark"] {
  --bg-color: #333333;
  --text-color: #ffffff;
}

body {
  background-color: var(--bg-color);
  color: var(--text-color);
}

Exercise Tips

  • Use prefers-color-scheme media query: @media (prefers-color-scheme: dark) { ... }.
  • Toggle theme with JavaScript: document.documentElement.setAttribute('data-theme', 'dark');
  • Add transition for smooth theme switching: transition: background-color 0.3s, color 0.3s;
  • Create multiple themes: [data-theme='blue'], [data-theme='green'], etc.

Code Editor

Output