An unofficial package to improve the compatibility of Radix Colors and Tailwind.
Warning
The following documentation is for version 2.x of this package. v1.0.0 of this package has an issue that makes it unable to display P3 colors. There is a v2.0.0-beta.x version available which fixes this issue.
npm install --save-dev windy-radix-palette @radix-ui/colors
Add the plugin to your Tailwind config:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
plugins: [colors.plugin],
};
Then you can use the classes in your markup!
<button class="bg-tomato-4 hover:bg-tomato-5 text-tomatoA-11">Button</button>
By default, this plugin will add CSS properties for all of the available Radix Colors. This adds many hundreds of CSS properties into your stylesheet. If this is an issue for your case, you can tell the plugin which colors you'd like it to generate for you:
const radixColors = require("@radix-ui/colors");
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin({
colors: {
mauveA: radixColors.mauveA,
mauveDarkA: radixColors.mauveDarkA,
red: radixColors.red,
redDark: radixColors.redDark,
},
});
module.exports = {
plugins: [colors.plugin],
};
The return value from createPlugin()
includes an alias
function. This function can be called to help create aliases for Radix Colors, or arbitrary values.
Creating semantic aliases for colors can be helpful to when it comes to theming. For example, in western culture, it would be common to see red
mapped to "danger", yellow
to "warning", and green
to "success".
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
danger: {
1: colors.alias("red.1"),
2: colors.alias("red.2"),
},
warning: {
1: colors.alias("yellow.1"),
2: colors.alias("yellow.2"),
},
success: {
1: colors.alias("green.1"),
2: colors.alias("green.2"),
},
},
},
},
};
If you wish to rename a scale, just omit the scale step from the alias:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
danger: colors.alias("red"),
warning: colors.alias("yellow"),
success: colors.alias("green"),
},
},
},
};
This will make danger-1
map to red-1
, danger-2
map to red-2
, etc.
When designing for both light and dark modes, you sometimes need to map a variable to one color in light mode, and another color in dark mode. Common examples include:
- Components that have a white background in light mode and a subtle gray background in dark mode. For example, Card, Popover, DropdownMenu, HoverCard, Dialog etc.
- Components that have a transparent black background in light mode and a transparent white background in dark mode. For example, Tooltip.
- Shadows that are saturated, transparent gray in light mode, and pure black in dark mode.
- An overlay that is light transparent black in light mode, and a darker transparent black in dark mode.
— Radix Colors
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
panel: colors.alias({
light: "white",
dark: "slate.2",
}),
"panel-contrast": colors.alias({
light: "blackA.9",
dark: "whiteA.9",
}),
shadow: colors.alias({
light: "slateA.3",
dark: "black",
}),
overlay: colors.alias({
light: "blackA.8",
dark: "blackA.11",
}),
},
},
},
};
It is also possible to use a mutable alias on an entire scale:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
overlay: colors.alias({
light: "blackA",
dark: "whiteA",
}),
},
},
},
};
You can also use the alias
function to create aliases for arbitrary values:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
surface: colors.alias({
light: "hsla(0, 0%, 100%, 0.9)",
dark: "rgba(0, 0, 0, 0.25)",
}),
},
},
},
};
The alias
function will try not to create any extra CSS variables if they aren't required. In the case of mutable aliases, however, a CSS variable must be created so that we have a consistent value to reference in Tailwind config.
By default, any CSS variables created will have the name --wrp-alias-<unique-id>
, where <unique-id>
is replaced with a randomly generated sequence of characters.
If you want to have control over the name of the generated variable, you can pass a name
property to your alias. The variable will use the name provided, for example, the following code will create a CSS variable --surface
:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
theme: {
extend: {
colors: {
surface: colors.alias({
name: "surface",
light: "hsla(0, 0%, 100%, 0.9)",
dark: "rgba(0, 0, 0, 0.25)",
}),
},
},
},
};
Use of Tailwind's opacity modifier is disabled by default. This means that classes like the following will not work with the default plugin configuration:
<button class="bg-red-9/50">Button</button>
This is partially an opinionated decision (the Radix Colors are hand-picked with purpose), but also because it makes support for the P3 colors included in Radix Colors v3 a much better experience for users of this plugin.
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin({
opacitySupport: true,
});
module.exports = {
plugins: [colors.plugin],
};
If you'd like to enable support for the opacity modifier, bear in mind that P3 colors will not be automatically applied when support is detected, and instead you will have to do this manually, with the help of the p3
modifier added by this plugin:
<button class="bg-red-9 p3:bg-redP3-9">Button</button>
By default, this plugin will add CSS properties to the :root
CSS pseudo-class. The selector where these properties are placed can be customized via the rootSelector
option. For example, when working with shadow DOM you might want to put the properties under the :host
selector:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin({
rootSelector: ":host",
});
module.exports = {
plugins: [colors.plugin],
};
The colors in this palette will automatically switch to the light/dark variant based on your Tailwind dark mode settings:
- When
darkMode
is not set, or is set to'media'
, the palette will change based on the user's preferred color scheme (prefers-color-scheme
) - When
darkMode
is set to'class'
, the palette will change based on the presence of the dark mode selector (defaults to.dark
), note that you can customize the dark mode selector if required
We also ship a typography preset that is meant to be used in combination with windy-radix-palette
and @tailwindcss/typography
. It adds custom color themes for all available Radix colors.
npm install --save-dev windy-radix-typography @tailwindcss/typography
Add it to your Tailwind config:
const { createPlugin } = require("windy-radix-palette");
const colors = createPlugin();
module.exports = {
plugins: [colors.plugin, require("@tailwindcss/typography")],
presets: [require("windy-radix-typography")],
};
Now you can use the prose themes in your markup:
<div class="prose prose-mauve">...</div>
Customization is done in the way you'd typically customize typography styles in Tailwind. Let's say that you want to make a
tags blue:
<div class="prose prose-slate prose-a:text-blue-11">...</div>
You probably don't need to use this plugin!
Here is one way you can use Radix Colors with Tailwind, without this plugin:
@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";
@import "@radix-ui/colors/slate";
@import "@radix-ui/colors/slate-alpha";
@import "@radix-ui/colors/slate-dark";
@import "@radix-ui/colors/slate-dark-alpha";
module.exports = {
// ...
theme: {
extend: {
colors: {
slate: {
1: "var(--slate-1)",
2: "var(--slate-2)",
3: "var(--slate-3)",
4: "var(--slate-4)",
5: "var(--slate-5)",
6: "var(--slate-6)",
7: "var(--slate-7)",
8: "var(--slate-8)",
9: "var(--slate-9)",
10: "var(--slate-10)",
11: "var(--slate-11)",
12: "var(--slate-12)",
a1: "var(--slate-a1)",
a2: "var(--slate-a2)",
a3: "var(--slate-a3)",
a4: "var(--slate-a4)",
a5: "var(--slate-a5)",
a6: "var(--slate-a6)",
a7: "var(--slate-a7)",
a8: "var(--slate-a8)",
a9: "var(--slate-a9)",
a10: "var(--slate-a10)",
a11: "var(--slate-a11)",
a12: "var(--slate-a12)",
},
},
},
},
};
<button class="dark:bg-slate-1 hover:bg-slate-a5 text-slate-12 bg-white">
Button
</button>
My reason for originally creating this plugin was to generate a version of the Radix Colors .css
files that used the .dark
selector, instead of .dark-mode
, which used to be the only selector used by Radix Colors for dark mode at the time.
What I didn't realize at that time was that Tailwind supports customizing the dark mode selector, so you would have been able to integrate the two pretty easily without the trouble of using a plugin.
Nowadays, Radix Colors dark mode actually also uses the .dark
selector as well, which means that it works nicely with Tailwind out of the box. In fact, there are examples of Radix and Tailwind integration on the Radix Primitives docs.