tailwindcss: Dark mode "class" strategy doesn't work with CSS Modules and @apply
Describe the problem:
Dark Mode in ‘class’ strategy doesn’t work with CSS Modules and @apply
. css-loader
renames .dark
selectors given by tailwind.
Link to a minimal reproduction:
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 17
- Comments: 21 (3 by maintainers)
No plans to spend time on this one unfortunately, I would recommend just writing the CSS a bit more manually when in a CSS module (same way you had to with apply for hover and stuff in Tailwind 1):
I’d be open to reviewing a PR if someone has an idea for making this work but no plans to work on this myself.
@webtinax I’m late to the party here but I was able to get this working without it being too hacky in Next.js v12 using a portion of @tosuke’s answer. It may work in older Next.js versions, but I haven’t tried it.
next.config.js
I’ve had some errors with the solution from @KyleRoss . I needed to pass also the options parameter to the default getLocalIdent.
Depends on the complexity the solution introduces and the trade-offs necessary to make it work.
For what it’s worth you can change the selector that’s generated for dark mode classes which means you can use the selector CSS modules needs:
The only issue here is if you are mixing regular CSS and CSS modules in the same project. If you’re doing that you’d need to use a separate config file for your CSS modules, which is easy in Tailwind now with the recently added
@config
directive.I briefly looked into this this morning to see if it’s easy to detect when a CSS file is a module or not, but it doesn’t look like we have any way to tell other than checking if the file name ends in
.module.css
, but that’s not sufficient because scoped style blocks in Vue behave like CSS modules and those won’t have that file name, and based on comments above in Angular the file name would often be*.component.css
instead.We could support some sort of special directive or comment that you include in the file to configure it, like this:
…but now we’re entering territory of significant additional complexity.
Again my real advice here taking a step back is just to not do this at all. Tailwind is meant to be used as utility classes in your HTML, that’s the intended workflow. The
@apply
feature is useful very occasionally in environments where it’s not common to componentize small things like buttons, but that’s it. If you’re using CSS modules, you’re probably not working on a Rails app or a Wordpress plugin where that is the case — you’re probably working with React where creating aButton.jsx
file is the norm, and you should just use utility classes in that file.I understand that a lot of people make heavy use of
@apply
to try and keep their HTML “clean” but that’s really not how the tool is meant to be used, and I think it sends a bad message to invest into making it easier to use the tool the wrong way.@tosuke @phuctm97 here is my solution: https://github.com/tailwindlabs/tailwindcss/discussions/3109#discussioncomment-335950
The workaround would still break certain aspects of the application tough. What we want is to get a tailwind utility with the dark:prefix to not be resolved to .dark when in a css-module but instead to be resolved to :global(dark). If someone choses to use a .dark class in his code, it should still be able to resolve regardless of tailwind‘s presence.
@adamwathan
And how is it in a nested css (or scss). For example:
If you’re using angular 2+ and you have this issue: just add encapsulation: ViewEncapsulation.None, to your component, as it follows:
And it gonna work like a charm 😄
Yeah I agree on this one , this needs described on their documentation. I did wasted couple of hours checking why this wasn’t working on the first place. Probably just adding to their documentation the :global approach will be enough for now
This here is the typical “tailwind” negligence. They brag about “Rapidly build modern websites” in their website, and then refuse to listen to actual developers describing actual needs.
The fact that both
dark:
variant is suggested in documentation, as well as@apply
is suggested in documentation suggests these two should work together.When you have two features in a library, people will want to use them together.
There is no reason this shouldn’t be added to library, other the the fact that there are “no plans”.
Workaround
Suppress renaming of
.dark
selectors. If you usecss-loader
, you can usegetLocalIdent
to suppress renaming.