Skip to content

Customizing colour for web experiences

Implementing custom color schemes in web applications using CSS variables, and OKLCH

Posted on:
3 min

A webpage on Stripe's website that showcases it's customization ability with the tagline "Your brand, your Checkout"

Cryptlex’s customers want the web applications facing their customers to be customized. Stripe Checkout is a similar web application that is customer facing. It showcases the customization with the tagline “Your brand, your Checkout”.

After evaluating customer requirements and the available market solutions, I narrowed solutions down to the following:

Using OKLCH looked straight-forward and it seemed that it would allow building a preview of the colour change in a relatively simple manner.

OKLCH implementation

Since the OKLCH solution, in theory, required the lowest effort, I decided to build a proof of concept for the same. The resulting color palettes/ramps were to be used with Angular Material.

Adam Argyle shows a modern and performant approach to generating colour palettes in a web application with OKLCH, that I found to be perfect for the use case.


/// Generates an OKLCH palette in CSS variables for a given name and hue.
@mixin generate-variables-for-hue($name, $value) {
  --#{$name}-hue: #{$value};

// Generate palette swatches
--x#{$name}-swatch-1: oklch(0.99 0.02 var(--#{$name}-hue));
...
--x#{$name}-swatch-10: oklch(0.05 0.13 var(--#{$name}-hue));

// Reference to palette swatches. Required for dark mode switch.
--#{$name}-swatch-1: var(--x#{$name}-swatch-1);
...
--#{$name}-swatch-10: var(--x#{$name}-swatch-10);
}

/// Swap Swatch 1 & Swatch 10, Swatch 2 and Swatch 9, and so on.
@mixin generate-dark-mode($name) {
  --#{$name}-swatch-1: var(--x#{$name}-swatch-10);
  ...
  --#{$name}-swatch-10: var(--x#{$name}-swatch-1);
}

The Angular documentation website has a ‘theme’ switching mechanism that swaps out multiple bundles of CSS to switch themes. All of these bundles contain the same rules with a different set of colours, set using a SCSS map at compile time. This approach has no regard for performance.

With the integration with Angular Material, I faced the following problems:

To my disappointment, the density cannot be set using a CSS variable which would have come in handy to create a Relaxed, Normal, and Compact view switch.

Next steps