Tailwind Material Colorsv3

A TailwindCSS plugin to use the Material Design 3 Color System with Tailwind, with Dynamic Color support.

Key features

Installation & Usage

npm install --save-dev tailwind-material-colors
tailwind.config.js
const { withMaterialColors } = require('tailwind-material-colors');

const config = {
// Your tailwind config.
};

module.exports = withMaterialColors(config, {
// Your base colors as HEX values. 'primary' is required.
primary: '#ff0000',
// secondary and/or tertiary are optional, if not set they will be derived from the primary color.
secondary: '#ffff00',
tertiary: '#0000ff',
// add any named colors you need:
green: '#00ff00',
blue: '#0000ff'
},
{
/* one of 'content', 'expressive', 'fidelity', 'monochrome', 'neutral', 'tonalSpot' or 'vibrant' */
scheme: 'content',
// contrast is optional and ranges from -1 (less contrast) to 1 (more contrast).
contrast: 0,
});

The colors you supply will be transformed by M3. In the example configuration above, where the provided primary base color is pure red, the resulting primary colors won't be, but they will have a red hue. This is an intentional effect of the M3 algorithm in the interest of good contrast ratios and pleasing aesthetics.

If you don't want a color to be harmonized to the primary color, pass { hex: "#xxxxxx", harmonize: false } as the value instead of the plain hex color.

What do I get?

1. A Tailwind color palette

The plugin will generate a color palette, structured like the one from the Material Theme Builder.

Primary
Secondary
Tertiary
Error
On Primary
On Secondary
On Tertiary
On Error
Primary Container
Secondary Container
Tertiary Container
Error Container
On Primary Container
On Secondary Container
On Tertiary Container
On Error Container
Surface Dim
Surface
Surface Bright
Inverse Surface
Surface Container Lowest
Surface Container Low
Surface Container
Surface Container High
Surface Container Highest
On Inverse Surface
Surface Variant
Inverse Primary
On Surface
On Surface Variant
Outline
Outline Variant
Scrim
Shadow

The generated colors can be used with any of Tailwind's usual utilities (such as bg-, text-, border-, fill-, stroke-, or shadow-).

2. Automatic surface/content color pairs

Most of the colors on the palette have an on-color counterpart. on-X is the default color of content inside an element with background color X.

For example, an element with a primary-container background will get on-primary-container content.

A bg- class will suffice to style both background and text color on most use cases.

Text color is on-primary-container by default
.bg-primary-container

3. Automatic dark mode

All the generated colors have both light and dark mode shades. Based on your defined Dark Mode Strategy, be it CSS prefers-color-scheme or a custom selector, they will change automatically. There's no need to use the dark: variant.

You can try it right here:

4. Interaction states

This plugin provides easy to use interaction states that follow the M3 guidelines. For every color with an on-color counterpart, an interactive-bg- utility will be generated.

Interactive elements use the concept of state layers: on hover or focus, the background color is overlayed with the on-color at certain amount of opacity (8% on hover, 12% on press and focus, and 16% on drag).

primary-container background
on-primary-container state layer with variable opacity
on-primary-container content
Content

This is achieved without CSS pseudoelements by directly changing the background color to the expected result.

All interactive colors
.interactive-bg-primary
.interactive-bg-secondary
.interactive-bg-tertiary
.interactive-bg-error
.interactive-bg-primary-container
.interactive-bg-secondary-container
.interactive-bg-tertiary-container
.interactive-bg-error-container
.interactive-bg-surface-dim
.interactive-bg-surface
.interactive-bg-surface-bright
.interactive-bg-inverse-surface
.interactive-bg-surface-container-lowest
.interactive-bg-surface-container-low
.interactive-bg-surface-container
.interactive-bg-surface-container-high
.interactive-bg-surface-container-highest
.interactive-bg-surface-variant

For drag states, use JavaScript to apply the dragged-bg-primary class instead of interactive-bg-primary while the element is being dragged.

Plugin configuration

Extending the Tailwind color palette

The plugin will add colors to the theme.colors key of your Tailwind config. Any custom colors already defined there will remain if there are no name conflicts, but as per the Tailwind docs, this disables the default Tailwind color palette. If you wish to keep it, add { extend: true } within the third argument of thewithMaterialColors call.

module.exports = withMaterialColors(config, colors, { scheme: 'content', extend: true });

Dynamic Color

You can update the generated theme at runtime, directly on client-side JavaScript, with the updateTheme function.

example.js
import { updateTheme } from "tailwind-material-colors/lib/updateTheme.esm";

const makeThemeRed = () => {
updateTheme({
// set a new primary color (and optionally any other colors in your theme)
primary: '#ff0000',
green: '#00ff00'
},
// second argument is your chosen dark mode strategy (usually 'media' or 'class')
'media',
// third argument is the scheme
'tonalSpot'
// fourth argument specifies contrast (optional)
0
);

It's recommended to set all colors when changing primary because the harmonize feature (on by default) will affect the resulting shades.

Known issues

Arbitrary background colors such as bg-[#000000] don't work when you use this plugin.