# Color Systems & Theming
Color plays a pivotal role in design. This chapter unpacks modern color models, palette generation, dark/light theme strategies, and the accent-color property. Learn to use LCH, OKLCH, and color functions for accessible, consistent designs.
# Table of Contents
- Color Models & Spaces
- Palette Generation & Scales
- Theming with Custom Properties
- Dark Mode & Light Mode Strategies
- Accent Color & UI Component Theming
- Gotchas & Best Practices
- Quick Cheatsheet
- Practice Tasks
- Review Questions
- Related Links
# Color Models & Spaces
CSS now supports LCH, OKLCH, LAB, and HSL, each with unique properties. LCH and OKLCH are perceptually uniform, meaning equal changes in value appear consistent to the human eye. Use them with color() or direct functions.
.primary {
--base: oklch(60% 0.2 250);
color: var(--base);
}
.warning {
color: lch(70% 0.2 20);
}
2
3
4
5
6
7
<p class="primary">OKLCH color example</p>
<p class="warning">LCH warning color</p>
2
Use color-mix() and color-contrast() to compute dynamic colors.
# Palette Generation & Scales
Generate color scales by mixing base colors with white/black or shifting hue/lightness. Use loops in preprocessors or define scales manually.
:root {
--blue-1: oklch(95% 0.02 260);
--blue-2: oklch(85% 0.04 260);
--blue-3: oklch(75% 0.06 260);
--blue-4: oklch(65% 0.08 260);
}
.btn {
background: var(--blue-3);
color: white;
}
.btn:hover { background: var(--blue-4); }
2
3
4
5
6
7
8
9
10
11
12
<button class="btn">OKLCH Button</button>
Tools like HSLuv, LCH generator, or design systems (Tailwind, Material) help produce balanced palettes. Always check contrast ratios.
# Theming with Custom Properties
Use custom properties to define themes. Override them in dark mode or at component scope. Combine with @property to register animatable color variables.
:root {
--color-bg: oklch(98% 0.02 250);
--color-fg: oklch(20% 0.03 260);
}
@media (prefers-color-scheme: dark) {
:root {
--color-bg: oklch(20% 0.03 260);
--color-fg: oklch(95% 0.02 250);
}
}
body {
background: var(--color-bg);
color: var(--color-fg);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
<div>Theme based on OKLCH colors</div>
# Dark Mode & Light Mode Strategies
There are multiple strategies: toggles, OS-based detection (prefers-color-scheme), or automatic theme generation via color-mix(). Provide neutral backgrounds and test content legibility. Use color-scheme property for form controls.
html {
color-scheme: light dark;
}
.switch {
display: inline-flex;
align-items: center;
gap: .5rem;
cursor: pointer;
}
.switch input {
appearance: none;
width: 2rem;
height: 1rem;
background: var(--track, #ccc);
border-radius: 1rem;
position: relative;
}
.switch input::before {
content: "";
position: absolute;
left: 0; top: 0;
width: 1rem; height: 1rem;
background: var(--thumb, #fff);
border-radius: 50%;
transform: translateX(0);
transition: transform .2s ease;
}
.switch input:checked::before { transform: translateX(1rem); }
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<label class="switch">
<input type="checkbox" onchange="document.documentElement.classList.toggle('dark', this.checked)">
Toggle Theme
</label>
2
3
4
# Accent Color & UI Component Theming
The accent-color property colors form controls (checkboxes, range sliders) according to your theme. Combine with CSS custom properties.
:root {
--accent: oklch(60% 0.2 200);
}
input[type="range"] {
accent-color: var(--accent);
}
2
3
4
5
6
<input type="range" value="50">
# Gotchas & Best Practices
- Some color functions are experimental; always provide sRGB fallbacks.
- Use perceptually uniform spaces (LCH/OKLCH) for mixing to ensure consistent brightness and saturation.
- Test color palettes on different monitors and in dark/light modes.
- Don’t forget to update color tokens in components when themes change.
- Always check contrast ratios in both dark and light themes.
# Quick Cheatsheet
- Color Spaces:
rgb(),hsl(),hwb(),lab(),lch(),oklab(),oklch(). - Functions:
color-mix(),color-contrast(),relative-color(). - Theming: custom properties,
prefers-color-scheme, toggles. - Accent:
accent-colorfor form controls. - Contrast: test with WCAG guidelines.
# Practice Tasks
- Generate a palette of five colors using OKLCH and apply it to a set of buttons. Ensure AAA contrast.
- Implement a theme switcher that toggles dark mode; update CSS variables accordingly.
- Use
color-mix()to create complementary colors on the fly and apply them to headings. - Apply
accent-colorto form controls and test across browsers.
# Review Questions
- Why are LCH and OKLCH preferred over HSL for palette generation?
- How can you generate color scales programmatically in CSS?
- Explain how
prefers-color-schemeinfluences CSS variables and thecolor-schemeproperty. - What is the purpose of
accent-colorand how does it relate to theming? - Describe the role of
color-contrast()in accessible design.