Giter VIP home page Giter VIP logo

tailwindcss-theming's Introduction

Tailwind CSS Theming GitHub release NPM release Top Language

Warning
I no longer use this package, so it is no longer maintained. If anyone want to take it over, feel free to ask.

Table of contents

Introduction

Note - This plugin works with Tailwind CSS v1.2 upwards.

tailwindcss-theming is a Tailwind CSS plugin made to solve the common need to have multiple themes in an application. It is also perfect for making dark themes.

It uses CSS Custom Properties in order to make your themes interchangeable on the client-side. Swapping themes is as simple as changing a class of your body element. See an example in CodeSandbox.

Moreoever, this plugin has full support for the prefers-color-scheme media query, so you can define a theme that will automatically be picked based on browser preferences.

Get started:

$ yarn add tailwindcss-theming@next --dev

Compatibility

This plugin is based on CSS Custom Properties, which are not compatible with IE11. You can have partial support for the browsers that do not support them by using a PostCSS plugin that add a fallback for CSS variables, such as postcss-css-variables or postcss-custom-properties.

Keep in mind that only your default theme will work with that method.

Alternatives

This plugin is feature-complete, but some alternatives exist. If you're looking for a simpler approach, a different kind of configuration, or just want to know the alternatives, here is a list that you may find useful:

A more complete comparison of the different theming plugins can be found here.

tailwindcss-theming's People

Contributors

dependabot[bot] avatar innocenzi avatar leesiongchan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tailwindcss-theming's Issues

Add `dark` and `light` variants

I wasn't initially going to make them available in this plugin, since they exist in another one, but I realized I sometimes needed to change stuff like font weight depending on the color scheme (eg. bold on dark and extrabold on light).

This can be done with CSS variable directly via the plugin, but it's more convenient to use a variant when it's a one-time case.

  • light variant
  • dark variant
  • no-preference variant

Add default themes/palettes

I'd like to add default themes so I can have something ready to use for every new project instead of having to either define a palette or copy a previous one.

For instance, I'd like to be able to require the plugin this way:

plugins: [
  require('tailwindcss-theming/themes/default')
]

For the default themes, I plan to deliver the following ones:

  • Tailwind 1 colors (themes/legacy?)
  • Tailwind 1.2 colors (the new palette Adam and Steve are working on, as themes/tailwind)
  • A custom light/dark theme based on Tailwind 1.2 colors (themes/default)

I'll wait for the official release of the new Tailwind color palette (it's actually in @tailwindcss/ui currently, but prone to changes) before adding this.

how can I avoid having all the default colours replaced?

Hi there, I'm giving your plugin and try and I would like to make gradual changes to my website so I can introduce a dark mode and possibly other themes.

I noticed when I followed your instructions that the moment I try to setup your plugin, it completely gets rid of all default Tailwind colours such as bg-white and bg-gray-500 etc

Even though I haven't even begun creating and using, and going through the code to replace colours by custom ones that can be themed. It would be nice if the default tailwind colours could co-exist with the custom ones. Is there something I can do to prevent all the default colours from being "replaced". Because right now they are not really "replaced" as you says in the docs.. they are completely removed and you are expected to replace them yourself which is a big job for a big website

Fix strategy precedence when applied to `html`

Currently, the assignable option makes the themes assignable (the manner depends on the choosen strategy), but the :root theme takes precedence if the strategy is applied to html.

For instance, <html data-theme="dark"> won't work because :root will take precedence.

I didn't realize this before because I was used to apply the strategies on body.

  • The "workaround" is to not use the strategy on html, but on anything else.
  • The fix is to modify the assignable themes' selectors.

Create a theme at runtime

Hi, thanks for your work! Is it possible to create a theme at runtime ? For example, based on the user settings. Or what would be a recommended approach to do so ?

Theme-based Tailwind variants

Is there any chance that you'll allow for more variants than dark, light and no-preference? It would be really helpful if you did

Object-based variant configuration

Instead of

//..
  .opacityVariant('muted', .35)
  .opacityVariant('pale', .50)

Be able to do

//..
  .opacityVariants({
    muted: .35,
    pale: .50
  })

Compatibility with TailwindUI?

Hello,
We're really excited to see what tailwindcss-theming can do. We spent most the day trying to get it to work along side tailwindui. It appears the plugins conflict somehow. Whichever plugin is listed first, writes the css - whichever follows, doesn't write anything after the :root stuff.

In tailwind.config.js, we have this in 'plugins'
plugins: [ require('@tailwindcss/ui'), require('tailwindcss-theming') ]

After running npm run build - none of the CSS Custom Properties are written (for things like .addColors).
If we change the order of the plugins, then it works, but the tailwindui colors aren't written.

Will you help?
(please and THANKYOU)

Example

Is there any example available?

Need a video how to use this :c

hello, thank you for made this. But I can't understand how to config it right? If have time, can you please make a video how to use it? :(
Thank you.

Multi-word, kebab-cased font variables get camel-cased

Thanks for creating the plugin!

So in the v3.0.0-beta.0 release (I haven't tried and don't plan on testing this in any older version of the plugin), when I try to use a multi-word, kebab-cased font variable name in my theme.config.js, it gets outputted in Tailwind as a camel-cased variable name after the font- prefix.

E.g.: .setVariable('sans-serif', ['Inter', 'Segoe UI', 'Roboto'], 'fontFamily') gets exported as font-sansSerif, when my original intent is to create a font-sans-serif class.

Would you be able to confirm if this is intended behavior, and if there would be any considerations for supporting/preserving kebab-cased variable names?

Tailwind 2 compatibility?

First of all thanks for the amazing work on this plugin, it really came at the right time for our project!

I'm currently trying to upgrade from tailwind 1.9.6 tailwind 2.0.2. After completing the upgrade guide I noticed the themes were not loading correctly. Looking at the generated css it seems all the color class names are being suffixed with -default now. For example the color named on-background will generate text-on-background-default.

This issue is happening in 2.4.3 and v3.0.0-beta.2.

Any ideas on how we complete the upgrade?

Variables created but classes not generated when using Astro.

Hello!

I am implementing the traditional light/dark mode for a website I am building using Astro.js. Initially, I decided to go for the Tailwind way of adding the dark: prefix over each class, but recently I decided to switch to this plugin workflow as I find it quite more comfortable.

The thing is, I am following the simple Quick Start but I don't see it working, and I don't know why. When using Astro, Tailwind works as an integration (as they call it) I suppose it could be something related to that.

This is my theme.config:

const { ThemeManager, Theme } = require('tailwindcss-theming/api');

const light = new Theme();
light.setName('light');
light.targetable();
light.addColors({

    'primary': '#FFFFFF',
});


const dark = new Theme();
dark.setName('dark');
dark.targetable();
dark.addColors({

    'primary': '#000000',
});

const themeManager = new ThemeManager();
themeManager.setDefaultTheme(light);
themeManager.setDefaultDarkTheme(dark);

module.exports = themeManager;

Then I import it to the Tailwind config:

'plugins': [

        require('tailwindcss-theming')({
        
	        themes: 'theme.config.cjs',
        }),
],

After that, I rebuild my project and test it, I add this div to the page on which I am testing the feature:

<div class = "h-screen bg-primary"></div>

But when I go to the corresponding page and try to manually update the theme via the DevTools (by adding the data-theme attribute) nothing happens. The variable is declared as you can see in the screenshot below, but it seems that the corresponding class bg-primary is not generated correctly (it doesn't even appear on the listed styles).

image

I apologize if I missed something on the configuration guide that could be causing this issue, but as I couldn't find why it happens or any kind of workaround, I thought to post this and see if anyone got the same issue or found a solution.

Thanks for the amazing work!

EDIT: I created an example project trying to set up this plugin with Astro. The exact same thing happens.

When I required theme.config.js IN tailwind.config.js, then failed to compile.

Failed to compile.

./app/javascript/stylesheets/application.scss (./node_modules/css-loader/dist/cjs.js??ref--7-1!./node_modules/postcss-loader/src??ref--7-2!./node_modules/sass-loader/dist/cjs.js??ref--7-3!./app/javascript/stylesheets/application.scss)
Module build failed (from ./node_modules/postcss-loader/src/index.js):
SyntaxError

(2:2) `@apply` cannot be used with `.text-gray-600` because `.text-gray-600` either cannot be found, or its actual definition includes a pseudo-selector like :hover, :active, etc. If you're sure that `.text-gray-600` exists, make sure that any `@import` statements are being properly processed *before* Tailwind CSS sees your CSS, as `@apply` can only be used for classes in the same CSS tree.

  1 | body {
> 2 |   @apply font-sans text-sm leading-normal text-gray-600;
    |  ^
  3 | }
  4 | 

Everything is JUST the same as "https://github.com/hawezo/tailwindcss-theming/blob/master/docs/setup.md",
But it just failed.

So how can I get it work.

Automatically define a variable's prefix

Currently, this:

setVariable('input', '#d2d6dc', 'borderColor')

will generate an --input variable by default. If no prefix is given, it should be infered from the path, borderColor in this case, to become --border-color-input.

how to use with custom utilities? such as for gradients

Hi there, wondering if you could assist in helping me understand how to add gradients to themes

Right now I have a custom gradients plugin:

const map = require('lodash/map');
const isPlainObject = require('lodash/isPlainObject');

const plugin = require('tailwindcss/plugin');

module.exports = plugin(({
  addUtilities, e, theme, variants,
}) => {
  const utilities = map(theme('gradients', {}), (gradient, name) => {
    const type = isPlainObject(gradient) && gradient.hasOwnProperty('type') ? gradient.type : 'linear';
    const colors = isPlainObject(gradient) ? gradient.colors || [] : gradient;

    return {
      [`.bg-gradient-${e(name)}`]: {
        background: `${type}-gradient(${colors.join(', ')})`,
      },
    };
  });

  addUtilities(utilities, variants('gradients', []));
});

and I define gradients like this in my tailwind.config.js:

module.exports = {
  theme: {
    gradients: {
      navbar: { type: 'linear', colors: ['90deg', '#98a8fb 0', '#71b3f8 100%'] },
    },
  },
  variants: {
    gradients: ['responsive', 'hover'],
  },
  plugins: [
    require('./tailwind-plugins/gradients.js'),
    require('./theme.config.js'),
  ],
};

How can I move this logic to your theme.config.js so that the gradients are associated with a theme, so I could have a different gradient applied when I switch from light to dark for example?

Many thanks!

Plugin not compatible with current version of Tailwind 1.1.x

I've used the prefers-scheme example of tailwindcss-theming and downgrade the Tailwind version to 1.1.3 and I get this error because ThemeBuilder is not a function:

Module build failed (from ./node_modules/postcss-loader/src/index.js):
TypeError: plugin is not a function
    at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/util/processPlugins.js:49:5
        at Array.forEach (<anonymous>)
	    at _default (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/util/processPlugins.js:48:11)
	        at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/processTailwindFeatures.js:33:58
		    at LazyResult.run (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:295:14)
		        at LazyResult.asyncTick (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:208:26)
			    at LazyResult.asyncTick (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:221:14)
			        at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:213:17

 @ ./node_modules/vue-style-loader??ref--7-oneOf-1-0!./node_modules/css-loader/dist/cjs.js??ref--7-oneOf-1-1!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src??ref--7-oneOf-1-2!./node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/vue-loader/lib??vue-loader-options!./src/App.vue?vue&type=style&index=0&id=7ba5bd90&lang=postcss&scoped=true& 4:14-385 14:3-18:5 15:22-393
  @ ./src/App.vue?vue&type=style&index=0&id=7ba5bd90&lang=postcss&scoped=true&
   @ ./src/App.vue
    @ ./src/main.ts
     @ multi (webpack)-dev-server/client?http://192.168.0.10:8080/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

 error  in ./src/css/app.css

Module build failed (from ./node_modules/postcss-loader/src/index.js):
TypeError: plugin is not a function
    at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/util/processPlugins.js:49:5
        at Array.forEach (<anonymous>)
	    at _default (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/util/processPlugins.js:48:11)
	        at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/tailwindcss/lib/processTailwindFeatures.js:33:58
		    at LazyResult.run (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:295:14)
		        at LazyResult.asyncTick (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:208:26)
			    at LazyResult.asyncTick (/home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:221:14)
			        at /home/kevin/web/tailwindcss-theming/examples/prefers-scheme/node_modules/postcss/lib/lazy-result.js:213:17

 @ ./src/css/app.css 4:14-161 14:3-18:5 15:22-169
  @ ./src/main.ts
   @ multi (webpack)-dev-server/client?http://192.168.0.10:8080/sockjs-node (webpack)/hot/dev-server.js ./src/main.ts

No type errors found
Version: typescript 3.5.3
Time: 2278ms

It should be mentionned at least in the documentation that this is experimental to Tailwind canary version.

[Feature request] Tailwind 1.4.0 support - new color opacity utilities

After TailwindCSS introduced new color opacity utilities current approach of opacity and colors generation became not inlined with the official way colors are generated in tailwindCSS.
As a result classes such as bg-opacity-25, text-opacity-25 makes no difference to the opacity level.

@hawezo I actually have mixed feelings about 1.4.0 color utilities and I like how you implemented it - more, but what can we do here? I guess when using tailwind-theming we should still have an access to full list of tailwind features. But what is really great about your approach with colors is that it's fully polyfillable for IE11 and 1.4.0 colors - are not. So maybe let's discuss what is the best thing that should be done here

Add `useTheme` composable function

Add a useTheme composable function, usable with the Vue Composition API, that will allow to keep track of the currently used theme, set a theme, or manually get the current theme, for an element.

The theme.config.js would be given to the use function (or detected), or some options would be passable to it.

The current theme on an element would be detected according to the detected strategy, the default theme in the configuration, and the current prefers-color-scheme.

A theme would be changeable, the use function would detected the strategy and update it accordingly.

Allow to add object as variant

const coolTheme = new Theme()
  .setName('cool-theme')
  .addColors({
    black: '#202121',
    white: '#ffffff',
    brand: {
      0: '#d1d4df',
      1: '#4b5f85',
      2: '#293142',
    },
  })
  .addOpacityVariant('hover', 0.1, ['brand']);

I have to use ['brand-0', 'brand-1'...] for now

theme.config.js file not found

Hi,

first thanks for this awesome plugin really like the
theme manager approach!

I've some problems to load the custom theme.config.js file.

  • I'm using tailwindcss-theming@next

image

The documentation is partly misleading but I tried all variations:

  • tailwind.config.js
      require('tailwindcss-theming')({
preset: 'nord'
})

      require('tailwindcss-theming'),

❌ documented in #18

module.exports = {
  theme: {},
  variants: {},
  plugins: [
    require('./theme.config.js')
  ],
};
  • theme.config.js

// eslint-disable-next-line @typescript-eslint/no-var-requires
const { ThemeManager, Theme } = require('tailwindcss-theming/api');


const light = new Theme()
  .setName('light')
  .targetable()
  .addColors({
    sun: '#717171',
    moon: '#717171',
    sparkles: '#717171',
    background: '#f1f1f1',
    'on-background': 'black',
  });

const dark = new Theme()
  .setName('dark')
  .targetable()
  .addColors({
    sun: '#ffd94d',
    moon: '#909090',
    sparkles: '#9e9ed6',
    background: '#212121',
    'on-background': 'white',
    });

module.exports = new ThemeManager()
  .setDefaultTheme(light)
  .setDefaultDarkTheme(dark);

Variants Clashing

Awesome library - thanks!

I'm needing to define multiple colorVariants on core colors like in the example below. As can be seen they are a light and dark variants of core colors accent and primary. These are not to be confused with a light and dark themes - they are unrelated - they are variants on the core theme colors of each theme.

When I build this I get an error Error: Variant light already exists.

I would have expected these to not clash since they are scoped uniquely. I have had a look at the source and notice that class ColorVariant does not consider the scope as part of it's uniqueness, hence the clashes.

As a workaround for now I will move the variant colors into the colors(...) definitions.

const lightTheme = new Theme()
  .name('light')
  .default()
  .assignable()
  .colors({
    'on-accent': '#FFFFFF',
    'accent': '#CB116E',

    'on-primary': '#292929',
    'primary': '#FAFAFA',
  })
  .colorVariant('light', '#FF569C', 'accent')
  .colorVariant('dark', '#940043', 'accent')
  .colorVariant('light', '#FFFFFF', 'primary')
  .colorVariant('dark', '#C7C7C7', 'primary');

Add custom variants

Add the ability to transform colors with custom plugins

.customVariant('slightly-lighter', function(color) {
  // color would be a TinyColor instance
  // https://github.com/typectrl/tinycolor
  // this method should return a TinyColor instance too
  return color.lighten(25)
})

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.