How to generate a full Tailwind CSS palette from a single color

Wed Apr 27 2022

You have an app where you allow users to select their brand color in order to style their website. Naturally, you use different shades of the color in your design - in some places you use ligher ones, and in other darker ones.

There are a lot of color generators and app that generate Tailwind CSS color palette for you. Here are some of my favorites:

Problem is, you want to have a simple UI and the thought of forcing users to select all possible shades gives you a headache.

Solution 1. "Opacity"

Official theming video from Tailwind CSS suggests adding a single (brand) color and then modify opacity (either text opacity or background opacity) to have lighter shades of your color.

<h1 class="text-brand text-opacity-75">Howdy</h1>

Under the hood Tailwind CSS uses CSS variables to modify alpha channel of the color (A in RGBA color model) which is pretty smart. Please watch the above YouTube video to see more detailed explanation but the gist of it is this:

.text-brand {
    --tw-text-opacity: 1;
    color: rgba(255, 255, 0, --tw-text-opacity);
}

This is fine and dandy but what to do when you want to have darker colors as well? You could start with a darker color and have a greater range. Can you tell your users to select "darker" color? No. You can't. You shouldn't.

Solution 2. "HSL"

For this reason I've been playing with HSL color model (where H stands for hue, S for saturation and L for lightness). By changing the L values (lightness) of a base color I was able to get OK looking palette for the whole range - both lighter and darker.

I've written a PHP package called Tailwind CSS Color Palette Generator to use exactly this to generate a full palette.

It is easy to generate a palette by specifying your base color:

use LukaPeharda\TailwindCssColorPaletteGenerator\Color;
use LukaPeharda\TailwindCssColorPaletteGenerator\PaletteGenerator;

// Create base color from hex
$baseColor = Color::fromHex('#ffff00');

// or from RGB
$baseColor = Color::fromRgb(255, 255, 0);

// or from HSL
$baseColor = Color::fromHsl(60, 100, 50);

// Generate a palette
$paletteGenerator = new PaletteGenerator;
$paletteGenerator->setBaseColor($baseColor);
$palette = $paletteGenerator->getPalette();

Generated $palette will be an array where keys are Tailwind CSS color steps and values Color objects:

$palette = [
    50 => Color,
    100 => Color,
    200 => Color,
    300 => Color,
    ...
];

You can then loop over it to generate CSS variables or use it anyway you see fit:

foreach ($palette as $key => $color) {
    echo '--color-brand-' . $key . ': #' . $color->getHex() . ';';
}

Extend color settings in your tailwind.config.js file and add brand color palette:

module.exports = {
    theme: {
        extend: {
            colors: {
                brand: {
                    50: 'var(--color-brand-50, #F5F3FF)',
                    100: 'var(--color-brand-100, #EDE9FE)',
                    200: 'var(--color-brand-200, #DDD6FE)',
                    300: 'var(--color-brand-300, #C4B5FD)',
                    400: 'var(--color-brand-400, #A78BFA)',
                    500: 'var(--color-brand-500, #8B5CF6)',
                    600: 'var(--color-brand-600, #7C3AED)',
                    700: 'var(--color-brand-700, #6D28D9)',
                    800: 'var(--color-brand-800, #5B21B6)',
                    900: 'var(--color-brand-900, #4C1D95)',
                }
            }
        }
    }
}

Afterwards you can use your color as regular CSS Tailwind class, for example as text-brand-100 or bg-brand-300.

Documentation and settings for fine tunning can be found here.

Generated palettes are not as great as the ones from the official Tailwind CSS color palettes but hey, those were carefully hand picked.

If you like this article consider tweeting or check out my other articles.