Package Exports
- tailwindcss-theme-variants
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (tailwindcss-theme-variants) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
This Tailwind CSS plugin registers variants for theming without needing custom properties. It has support for responsive variants, extra stacked variants, media queries, and falling back to a particular theme when none matches.
Installation
npm install --save-dev tailwindcss-theme-variants
Basic usage
Using selectors to choose the active theme
With this Tailwind configuration,
const { tailwindcssThemeVariants } = require("tailwindcss-theme-variants");
module.exports = {
theme: {
backgroundColor: {
"gray-900": "#1A202C",
},
},
variants: {
backgroundColor: ["light", "dark"],
},
plugins: [
tailwindcssThemeVariants({
themes: {
light: {
selector: ".light-theme",
},
dark: {
selector: ".dark-theme",
},
},
}),
],
};
this CSS is generated:
.bg-gray-900 {
background-color: #1A202C;
}
:root.light-theme .light\:bg-gray-900 {
background-color: #1A202C;
}
:root.dark-theme .dark\:bg-gray-900 {
background-color: #1A202C;
}
💡 You can choose more than just classes for your selectors. Other, good options include data attributes, like [data-padding=compact]
. You can go as crazy as .class[data-theme=light]:dir(rtl)
, for example, but at that point you need to be careful with specificity!
Using media queries to choose the active theme
You may rather choose to tie your theme selection to matched media queries, like prefers-color-scheme
:
const { tailwindcssThemeVariants, prefersLight, prefersDark } = require("tailwindcss-theme-variants");
module.exports = {
theme: {
backgroundColor: {
"teal-500": "#38B2AC",
},
},
variants: {
backgroundColor: ["light", "dark"],
},
plugins: [
tailwindcssThemeVariants({
themes: {
light: {
mediaQuery: prefersLight /* "@media (prefers-color-scheme: light)" */,
},
dark: {
mediaQuery: prefersDark /* "@media (prefers-color-scheme: dark)" */,
},
},
}),
],
};
Which generates this CSS:
.bg-teal-500 {
background-color: #38B2AC
}
@media (prefers-color-scheme: light) {
.light\:bg-teal-500 {
background-color: #38B2AC;
}
}
@media (prefers-color-scheme: dark) {
.dark\:bg-teal-500 {
background-color: #38B2AC;
}
}
💡 Keep the variants
listed in the same order as in themes
in this plugin's configuration for consistency and the most expected behavior. As you see above, light
came first, then dark
in backgroundColor
's variants
, so we also list light
before dark
in tailwindcssThemeVariants
's themes
option.
Full configuration
This plugin expects configuration of the form
{
themes: {
[name: string]: {
// At least one is required
selector?: string;
mediaQuery?: string;
}
};
baseSelector?: string;
fallback?: string | boolean;
rename?: (themeName: string) => string;
variants?: {
// The name of the variant -> what has to be done to the selector for the variant to be active
[name: string]: (selector: string) => string;
};
}
Where each parameter means:
themes
: an object mapping a theme name to the conditions that determine whether or not the theme will be active.selector
: a selector that has to be active onbaseSelector
for this theme to be active. For instance, ifbaseSelector
ishtml
, andthemes.light
'sselector
is.light-theme
, then thelight
theme's variant(s) will be in effect wheneverhtml
has thelight-theme
class on it.mediaQuery
: a media query that has to be active for this theme to be active. For instance, if thereduced-motion
theme hasmediaQuery
"@media (prefers-reduced-motion: reduce)"
(importable asprefersReducedMotion
), then thereduced-motion
variant(s) will be active.
baseSelector
(default":root"
): the selector that each theme'sselector
will be applied to to determine the active theme.fallback
(defaultfalse
): chooses a theme to fall back to when none of the media queries or selectors are active. You can either manually select a theme by giving a string like"solarized-dark"
or implicitly select the first one listed inthemes
by givingtrue
.rename
(default is a function that gives back exactly what was passed, as inrename("red") === "red"
, i.e. no renaming actually takes place): a function for renaming every theme, which changes the name of the generated variants.The most usual way to use this is to add a prefix or suffix to reduce duplication. For example, you can
rename: (themeName) => `${themeName}-theme`
to makethemes: { red, green, blue }
have corresponding variantsred-theme
,green-theme
, andblue-theme
. This also means that their generated class names are likered-theme\:bg-green-300
instead of justred\:bg-green-300
.variants
(default is nothing): an object mapping the name of a variant to a function that gives a selector for when that variant is active.For example, the importable
even
variant takes aselector
and returns`${selector}:nth-child(even)`
. The importablegroupHover
(which you are recommended to name"group-hover"
for consistency) variant returns`.group:hover ${selector}`
Examples
💡 At the time of writing, this documentation is a work in progress. For all examples, where I've done my best to stretch the plugin to its limits (especially towards the end of the file), see the test suite in tests/index.ts
.
Fallback
TODO
Stacked variants
💡 All of Tailwind CSS's core variants are bundled for use with the plugin. You can see the full list in src/variants.ts
.
TODO
TODO
Using both selectors and media queries
TODO
TODO: Show active theme tables for every example
License and Contributing
MIT licensed. There are no contributing guidelines. Just do whatever you want to point out an issue or feature request and I'll work with it.
Alternatives
TODO: theming plugin comparison table
Native screens | tailwindcss-dark-mode | tailwindcss-darkmode | tailwindcss-prefers-dark-mode | tailwindcss-theme-swapper | tailwindcss-theme-variants | tailwindcss-theming | |
---|---|---|---|---|---|---|---|
Controllable with selectors (classes or data attributes) | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Responsive | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | |
Requires custom properties | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ |
Supports prefers-color-scheme: dark |
✅ | With JavaScript | ❌ | ✅ | ✅ | ✅ | ✅ |
Supports prefers-color-scheme: light |
✅ | With JavaScript | ❌ | ❌ | ✅ | ✅ | ✅ |
Other thing |
Repository preview image generated with GitHub Social Preview