New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tailwindcss-theme-variants

Package Overview
Dependencies
Maintainers
1
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tailwindcss-theme-variants

JavaScript- or media-query-based theme variants with fallback for Tailwind CSS

  • 0.3.0
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
669
decreased by-26.64%
Maintainers
1
Weekly downloads
 
Created
Source

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 on baseSelector for this theme to be active. For instance, if baseSelector is html, and themes.light's selector is .light-theme, then the light theme's variant(s) will be in effect whenever html has the light-theme class on it.

    • mediaQuery: a media query that has to be active for this theme to be active. For instance, if the reduced-motion theme has mediaQuery "@media (prefers-reduced-motion: reduce)" (importable as prefersReducedMotion), then the reduced-motion variant(s) will be active.

  • baseSelector (default ":root"): the selector that each theme's selector will be applied to to determine the active theme.

  • fallback (default false): 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 in themes by giving true.

  • rename (default is a function that gives back exactly what was passed, as in rename("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 make themes: { red, green, blue } have corresponding variants red-theme, green-theme, and blue-theme. This also means that their generated class names are like red-theme\:bg-green-300 instead of just red\: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 a selector and returns `${selector}:nth-child(even)`. The importable groupHover (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 screenstailwindcss-dark-modetailwindcss-darkmodetailwindcss-prefers-dark-modetailwindcss-theme-swappertailwindcss-theme-variantstailwindcss-theming
Controllable with selectors (classes or data attributes)
Responsive
Requires custom properties
Supports prefers-color-scheme: darkWith JavaScript
Supports prefers-color-scheme: lightWith JavaScript
Other thing

Repository preview image generated with GitHub Social Preview

Keywords

FAQs

Package last updated on 19 Jul 2020

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc