Smart web design. Part II: Customizable color theme in 10 minutes 🦜⏱
Tags: css, html, web, ui
Published: 2019-10-02 09:47:09

---
title: Smart web design. Part II: Customizable color theme in 10 minutes 🦜⏱
published: true
description: How to organize colors using CSS variables to make you design customizable.
tags: css, html, web, ui
series: Smart web design
cover_image: https://thepracticaldev.s3.amazonaws.com/i/m2917692brm7zgcfpjf2.jpg
---

Customizable color palette use css variables for color values to make it easy to change via JS or CSS. But good theme requires colors with shades.

## HSL vs RGB

The oldest and the most popular color model on the Web is RGB (Red, Green, Blue). It has pretty simple and short syntax `#ff0000` (red). But it's really hard to remember all the combinations of colors and manipulate them without color picker.

But there is one color scheme which is extremely simple in work! It's [HSL](https://en.wikipedia.org/wiki/HSL_and_HSV) (Hue, Saturation, Lightness):

  * Hue tells wether the color be blue, red, yellow, green or violet, it refers to color wheel angle.
  * Saturation tells how much hue is there, wether it fade (0%) or bright (100%).
  * Lightness tells wether it dark (0%, black) or light (100%, white).

HSL represents colors in more human way. Red in HSL is `hsl(0, 100%, 50%)` to turn it into blue we just need to change hue param `hsl(200, 100%, 50%)`.

## Theme Colors

Now we need to define theme colors. We will create duotone theme, but you can use as much colors as you need, just don't overdo it. Let's call our colors major and minor. To receive color shades we will change the lightness parameter. Shades will be named with two digit indexes from lightest to darkest, e.g. `--major-10` lightest and `--major-90` darkest.

```css
:root {
  /* Major color is red */
  --major-5: hsl(0, 100%, 95%);
  --major-10: hsl(0, 100%, 90%);
  --major-30: hsl(0, 100%, 70%);
  --major-50: hsl(0, 100%, 50%);
  --major-70: hsl(0, 100%, 30%);
  --major-90: hsl(0, 100%, 10%);

  /* Minor color is yellow */
  --minor-5: hsl(50, 100%, 95%);
  --minor-10: hsl(50, 100%, 90%);
  --minor-30: hsl(50, 100%, 70%);
  --minor-50: hsl(50, 100%, 50%);
  --minor-70: hsl(50, 100%, 30%);
  --minor-90: hsl(50, 100%, 10%);

  --bg: white; /* background color */
  --fg: black; /* text color */
}
```


Live demo:
{% jsfiddle https://jsfiddle.net/rumkin/y8pexrbu/60/ result,css,html,js %}

## Advanced theming

You can customize colors using custom css files in combination with media queries. For example printable version could be black and white only.

Basic `theme.css` file could look like this:

```css
:root {
  --major-10: hsl(0, 100%, 90%);
  /* ... */
  --minor-10: hsl(50, 100%, 90%);
  /* ... */

  --bg: white;
  --fg: black;
}
```

### Dark theme

Dark theme section in `theme.css`:

```css
@media (prefers-color-scheme: dark) {
  :root {
    --major-10: hsl(0, 100%, 90%);
    /* ... */
    --minor-10: hsl(50, 100%, 90%);
    /* ... */

    --bg: black;
    --fg: white;
  }
}
```

### Printable version

Printable theme section in `theme.css`:

```css
@media print {
  :root {
    --major-10: hsl(0, 0%, 90%);
    /* ... */
    --minor-10: hsl(50, 0%, 90%);
    /* ... */
  }
}
```

## Theme switching

There is a lot of options how to implement a switcher, but the simplest one is a switcher that changes link or style elements order, moving the target theme related element to the end of children list. This is how it implemented in live preview:

```js
function applyTheme(name) {
  // Find style element with matching id
  const style = document.getElementById(name + 'Theme')
  
  // Move it to the end of child list
  const parent = style.parentElement
  parent.removeChild(style)
  parent.appendChild(style)
  
  // Remember user's choise
  localStorage.setItem('theme', name)
}

// Get switcher
const switcher = document.getElementById('themeSwitcher')

// React on select input value changed
switcher.addEventListener('change', (e) => {
  useTheme(e.target.value)
})

// Select color in select input and apply theme selection
applyTheme(
  switcher.value = localStorage.getItem('theme')
)

```

## ⚠️ Accessibility

Please, don't forget to include high contrast themes in your design. It will be very helpful for people with color blindness.

## Conclusion

That's all. Now you know how simple it is to create a customizable CSS design for you site. Using [favicon-switcher](https://github.com/rumkin/favicon-switcher) from my previous article ["Smart web design. Part I: light/dark mode favicon."](https://dev.to/rumkin/smart-web-design-part-i-light-dark-mode-favicon-31f0) you able to make real stunning design.

## Credits

Cover image by [David Clode](https://unsplash.com/@davidclode?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText) on [Unsplash.com](https://unsplash.com/?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText).