Overview
The EDS Colour Palette Generator creates consistent, accessible colour scales for design systems. It uses a Gaussian (bell curve) distribution to maintain visual harmony across different lightness levels.
The tool works in the OKLCH colour space — a perceptually uniform model where equal numerical changes produce equal perceived differences. This makes it ideal for programmatic colour generation.
How it works
1. Define lightness values
Each colour scale step has a predefined lightness value chosen to meet contrast requirements:
- Background colours: High lightness in light mode (0.97–0.999), low in dark mode (0.15–0.25)
- Border colours: Mid-range values for subtle to strong emphasis
- Fill colours: Values optimised for interactive elements
- Text colours: Values ensuring WCAG AA/AAA compliance
Lightness values are configured separately for light and dark modes to ensure optimal contrast in both.
2. Apply Gaussian distribution to chroma
While lightness is fixed, chroma (colour intensity) varies using a Gaussian function. This creates natural colour progression — colours are most vibrant at a specific lightness level (the mean) and gradually become more muted as you move away from it.
The function outputs a multiplier (0–1) applied to the base colour's chroma at each step.
3. Generate colour scale
For each step:
- Convert the base colour to OKLCH colour space
- Set the lightness to the predefined value for that step
- Calculate the chroma multiplier using the Gaussian function with the step's lightness
- Apply the multiplier to the base colour's chroma: new_chroma = base_chroma × multiplier
- Keep the hue unchanged from the base colour
This ensures colours maintain their hue identity while adapting intensity to suit different lightness levels.
The Gaussian bell curve
The bell curve determines how chroma is distributed across lightness values. Adjust the mean and standard deviation to see how they affect curve shape and colour intensity at different lightness levels.
How it works: The bell curve (Gaussian function) determines how much chroma (color intensity) is applied at different lightness levels.
- Mean: The lightness value where chroma is at its maximum
- Standard deviation: How quickly chroma decreases away from the mean
- Higher values near the mean = more vibrant colors
- Lower values away from the mean = more muted colors
Interactive chroma distribution
Experiment with different base colours and Gaussian parameters to see how they affect the final colour scale. The chart shows how chroma varies across the lightness spectrum.
Base color properties:
- Base chroma: 0.181
- Max chroma in scale: 0.179
- Peak at lightness: 0.57
Chroma distribution
Generated color scale
Hover over each step to see its index. Notice how chroma (color intensity) peaks near the mean lightness value.
Chroma calculation formula:
chroma = gaussian(lightness, mean, stdDev) × baseChroma
Where the Gaussian function outputs a multiplier between 0 and 1, which scales the base color's chroma based on the lightness value's distance from the mean.
Why OKLCH colour space?
OKLCH is a cylindrical representation of the Oklab colour space, designed to be perceptually uniform. It has three components:
- Lightness (L)
- Ranges from 0 (black) to 1 (white). Perceptually uniform — 0.5 is truly medium lightness.
- Chroma (C)
- Colour intensity or saturation. 0 is greyscale, higher values are more vibrant. Unlike HSL, chroma is consistent across hues.
- Hue (H)
- The colour angle (0–360 degrees). Represents the basic colour quality (red, green, blue, etc.).
By adjusting lightness and chroma independently while keeping hue constant, we create colour scales that look natural and maintain consistent relationships.
Configuration options
Lightness values
Each step has predefined lightness values for light and dark modes, based on:
- APCA contrast requirements
- WCAG 2.1 Level AA/AAA guidelines
- Visual hierarchy needs (backgrounds, borders, text)
- Interactive state differentiation (default, hover, active)
Gaussian parameters
Mean
The lightness value where chroma reaches maximum. Typically set to 0.6 for light mode and 0.7 for dark mode to ensure vibrant mid-tones.
Standard deviation
Controls how quickly chroma decreases away from the mean. Lower values create sharper peaks (dramatic variation), higher values create gentler curves (gradual changes).
Separate light/dark modes
Light and dark modes use different Gaussian parameters because:
- Dark mode typically needs higher chroma in lighter colours to maintain visibility
- Light mode benefits from vibrant mid-tones but muted extremes
- Different background lightness ranges require different chroma distributions
Colour step pairings and contrast requirements
Each colour step is designed to work with specific other steps to ensure accessibility. The configuration defines contrast requirements using both APCA (Accessible Perceptual Contrast Algorithm) and WCAG 2.1 standards.
These requirements come directly from the configuration file, keeping documentation in sync with implementation. Each pairing specifies minimum contrast levels for different use cases — from subtle UI components to body text.
Understanding the levels:
- APCA Lc values: Range from 15 (decorative elements) to 90 (body text). Higher values mean stronger contrast requirements.
- WCAG ratios: Traditional contrast ratios (3:1, 4.5:1, 7:1) for UI components, normal text, and large text at AA/AAA levels.
Background Fill Muted Default
Category: Background Fill Muted • Variant: default
Contrast requirements with:
Background Surface
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Background Fill Muted Hover
Category: Background Fill Muted • Variant: hover
Contrast requirements with:
Background Surface
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Background Fill Muted Active
Category: Background Fill Muted • Variant: active
Contrast requirements with:
Background Surface
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Border Subtle
Category: Border • Variant: subtle
Contrast requirements with:
Background Canvas
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Border Medium
Category: Border • Variant: medium
Contrast requirements with:
Background Canvas
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Fill Muted Default
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Border Strong
Category: Border • Variant: strong
Contrast requirements with:
Background Canvas
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Fill Muted Default
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Fill Muted Hover
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Border Medium
- Dividers, borders, and thick focus outlines: Lc ≥ 15 and ≥5px in smallest dimension.
- Anything below Lc 15 is not reliably visible.
- Interactive components
- Graphical objects needed to understand content
Background Fill Emphasis Default
Category: Background Fill Emphasis • Variant: default
Contrast requirements with:
Background Canvas
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Fill Emphasis Hover
Category: Background Fill Emphasis • Variant: hover
Contrast requirements with:
Background Canvas
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Fill Emphasis Active
Category: Background Fill Emphasis • Variant: active
Contrast requirements with:
Background Canvas
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Background Surface
- Applies to placeholders, disabled text, copyright/™ bugs.
- Large, solid, easily recognizable UI graphics: Lc ≥ 30.
- Interactive components
- Graphical objects needed to understand content
Text Subtle
Category: Text • Variant: subtle
Contrast requirements with:
Background Canvas
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Surface
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Fill Muted Default
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Text Strong
Category: Text • Variant: strong
Contrast requirements with:
Background Canvas
- Body text: ≥14px/400 or heavier/larger.
- Large fluent text: maximum Lc 90 when bold and >36px.
- Small/medium text: no maximum.
- Normal text: <24px and <19px bold.
Background Surface
- Body text: ≥14px/400 or heavier/larger.
- Large fluent text: maximum Lc 90 when bold and >36px.
- Small/medium text: no maximum.
- Normal text: <24px and <19px bold.
Background Fill Muted Default
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Text Subtle on Emphasis
Category: Text • Variant: subtle-on-emphasis
Contrast requirements with:
Background Fill Emphasis Default
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Fill Emphasis Hover
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Fill Emphasis Active
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Text Strong on Emphasis
Category: Text • Variant: strong-on-emphasis
Contrast requirements with:
Background Fill Emphasis Default
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Fill Emphasis Hover
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Background Fill Emphasis Active
- Labels, short copy, helper text: ≥24px/400 or ≥16px/700.
- Normal text: <24px and <19px bold.
Key insights
- Background steps (Canvas, Surface) need minimal contrast between each other but high contrast with text elements
- Fill elements have progressive contrast requirements based on emphasis level (muted vs. emphasis)
- Border steps maintain visual hierarchy through three levels (subtle, medium, strong)
- Text elements have the strictest requirements — different levels for subtle text, strong text, and text on emphasis backgrounds
- Interactive states (default, hover, active) are differentiated through lightness and contrast requirements
Best practices
- ✓
Start with a well-saturated base colour
The Gaussian function scales down from the base chroma. Starting with higher chroma gives more flexibility.
- ✓
Test contrast ratios regularly
Enable contrast checking to ensure all colour combinations meet accessibility requirements.
- ✓
Export and version your configurations
Save your palette configurations to maintain consistency and track changes over time.