ColorThemes

v5.x.x

Description

The ColorThemes plugin generates token-based color themes in Tailwind by mapping color values to CSS custom properties. It generates utility classes that resolve to CSS variables with fallback values, allowing colors to be dynamically overridden at runtime via theme classes.

Supported Properties

The theme system currently supports the following property groups:

  • Text color
  • Background color
  • Border color
  • Outline color
  • Ring color

How It Works

The ColorThemes plugin maps semantic color names (e.g. primary, title) to CSS custom properties.

  • Default values are defined via Tailwind utilities (e.g. text-primary, bg-primary)
  • Theme classes (e.g. .theme-accent-1) override these values using CSS variables
  • Utilities resolve to CSS variables with fallback values
Generated CSS
.text-primary {
  color: var(--text-primary, var(--color-grey-90));
}

This allows themes to dynamically override colors at runtime without changing markup. If a theme does not define a value, the fallback token is used.

Setup

tailwind.config.js
const { ColorTokens, ColorThemes } = require('@area17/a17-tailwind-plugins');

module.exports = {
  ...
  plugins: [ColorTokens, ColorThemes],
  theme: {
    colors: {
      "white": "#fff",
      "grey-3": "#f8f8f8",
      "grey-5": "#f2f2f2",
      "grey-10": "#e6e6e6",
      "grey-15": "#d9d9d9",
      "grey-30": "#b3b3b3",
      "grey-54": "#757575",
      "grey-90": "#1a1a1a",
      "black": "#000",
      "blue-01": "#0A152B",
      "blue-02": "#001F5C",
      "blue-03": "#004F91",
      "blue-04": "#313BFB",
      "blue-05": "#81EEF3",
      "blue-06": "#ADD8E6",
      "red-01": "#f00",
      "green-10": "#F3F7F5",
      "green-20": "#E6F4EF",
      "green-30": "#CDE9DE",
      "green-40": "#9FD8C3",
      "green-50": "#4CBF99",
      "green-60": "#158F6A",
      "green-70": "#1F6F54",
      "green-90": "#0B3D2E",
      "purple-10": "#F8F5FC",
      "purple-20": "#F4EFFB",
      "purple-30": "#E7DDF7",
      "purple-40": "#D1C4EE",
      "purple-50": "#A78BDA",
      "purple-60": "#7A57B8",
      "purple-70": "#5B3A8A",
      "purple-90": "#3A1F5D"
    },
    borderColor: ApplyColorVariables(colors, {
        primary: "grey-5",
        secondary: "grey-10",
        tertiary: "grey-15"
      }
    ),
    textColor: ApplyColorVariables(colors, {
        title: "black",
        primary: "grey-90",
        inverse: "white",
        secondary: "grey-54",
        accent: "blue-01",
      }
    ),
    backgroundColor: ApplyColorVariables(colors, {
        primary: "white",
        secondary: "grey-15",
        banner: "grey-90",
        accent: "blue-03",
        column: "blue-05",
        column-alt: "blue-04",
        code: "grey-10",
        inverse: "black",
      }
    ),
    colorThemes: {
      "accent-1": {
        "text": {
          "title": "green-90",
          "primary": "green-90",
          "secondary": "green-70",
          "accent": "green-60"
        },
        "background": {
          "primary": "green-20",
          "secondary": "green-30",
          "inverse": "green-90",
          "accent": "green-10"
        },
        "border": {
          "primary": "green-50",
          "secondary": "green-40"
        }
      },
      "accent-2": {
        "text": {
          "title": "purple-90",
          "primary": "purple-90",
          "secondary": "purple-70",
          "accent": "purple-60"
        },
        "background": {
          "primary": "purple-20",
          "secondary": "purple-30",
          "accent": "purple-10"
        },
        "border": {
          "primary": "purple-50",
          "secondary": "purple-40"
        }
      }
    },
  }
  ...
};

Demo

Theme classes are generated based on the keys in the colorThemes config. For example, if we name our theme accent-1, we get a class of .theme-accent-1.

No theme, default colors

Lorem ipsum dolor sit amet ut aliquet eros laoreet mi fringilla justo.

In laoreet habitasse lacus orci senectus iaculis magna neque sollicitudin sapien nullam.

With .theme-accent-1 applied

Lorem ipsum dolor sit amet ut aliquet eros laoreet mi fringilla justo.

In laoreet habitasse lacus orci senectus iaculis magna neque sollicitudin sapien nullam.

With .theme-accent-2 applied

Lorem ipsum dolor sit amet ut aliquet eros laoreet mi fringilla justo.

In laoreet habitasse lacus orci senectus iaculis magna neque sollicitudin sapien nullam.

Minimal Example

A simple theme can be created by mapping semantic keys to color tokens in the colorThemes config.

tailwind.config.js
colorThemes: {
  brand: {
    text: {
      primary: "blue-03"
    }
  }
}

This generates a theme class .theme-brand that overrides the text-primary utility.

document.html
<div class="theme-brand">
  <p class="text-primary">This text is themed</p>
</div>

The text will render using the blue-03 token when the theme is applied, and fall back to the default text-primary color when it is not.

Theme Reset

The .theme-reset class can be used to revert themed content back to the default token values.

This is useful when nesting themes and you want a section to ignore an inherited theme and use the base colors instead.

document.html
<div class="theme-accent-1">
  <p class="text-primary">Themed text</p>

  <div class="theme-reset">
    <p class="text-primary">Default text</p>
  </div>
</div>

The inner content will use the default color values, ignoring the parent theme.

Usage Guidelines

Theme values must reference existing color tokens

Theme color values should reference defined color tokens (e.g. blue-03). Named colors like "blue" will not work unless they exist as tokens.

Theme classes must wrap content

The theme class must be applied to a parent element. Utility classes on the same element will not inherit theme values.

For example, this will not work as expected:
document.html
<div class="theme-accent-1 bg-primary"></div>

Instead, wrap the element:

document.html
<div class="theme-accent-1">
  <div class="bg-primary"></div>
</div>

Theme keys must exist in the base token set

All theme keys (e.g. primary, title, etc.) must be defined in the default token set. New keys cannot be introduced in the theme config. This ensures that a valid fallback color is always available.