Is there any better solution for this issue? I don't have control over the html so adding the class is not an option.
Sorry if this was asked before. Thanks for your work!
EDIT: My workaround has been defining an extra class for hover styles and then applying that to whatever selectors I need to use it with:
The issue description confuses me a bit. Are you saying that
.btn-orange
is
or
is not
applied to the input element?
&:hover {
@apply .text-teal;
Please have a look at this Tutorial ..
https://youtu.be/3pN9EcFvPxo?list=PLht-7jHewMA4KfgZGHNyEx3mD-OJjaasM&t=145
I followed it and have to add the dots to make it work! like in the video
Ok, I wasn't too clear in the original post, so let me clarify.
@hacknug is right about the workaround, that's a better solution, but still a lot of extra work if you use SCSS and hover styles often.
(the dots are not required, but I'll add them now to avoid confusion)
.btn {
@apply .bg-red;
&:hover {
@apply .bg-black;
button {
@apply .btn;
This is the shortest representation of the issue. This generates the following CSS:
.btn {
background-color: #e3342f;
.btn:hover {
background-color: #22292f;
button {
background-color: #e3342f;
So the hover styles are lost. It's because the &:hover
creates a new CSS rule, so when applying .btn
to other elements, .btn:hover
is left out.
This is usually not an issue, adding .btn
to a real HTML element works as expected.
<button class="btn">Push</button>
In this example the button receives the hover styles. Actually there is no Tailwind here, this is just basic SCSS. The 'Tailwind solution' to this issue would be:
<button class="bg-red hover:bg-black">Push</button>
I guess this is how Tailwind was intended to be used, adding TW classes to the Markup. But for my usecase I need to style elements where I don't want to clutter the html and keep the style in the scss files and still use TW's short css styling.
In the TW example .hover:bg-black
is actually a class generated according to the tailwind.js file. So I don't see any easy solutions to this since .hover:btn
would need to exist, plus it would need to be applied with the @apply .btn;
line. (every time .btn
is used, you want the new class work similar to the applied class)
I'm not sure if it's possible.
Scanning for every @apply
-ed class and checking if they also have a corresponding .class:hover
line. (same for focus, etc.)
If so, then creating .hover:class
extra classes similarly to the built-in classes.
And also applying them to the @apply
-ed classes.
So in this ideal world the output CSS would look like this:
.btn {
background-color: #e3342f;
.btn:hover {
background-color: #22292f;
.hover\:btn:hover {
background-color: #22292f;
button {
background-color: #e3342f; // comes from `@apply .btn;`
button:hover {
background-color: #22292f; // theoretically comes from `@apply .hover:btn;`
Does that make any sense?
@adamwathan said on his post about going full-time with Tailwind that he's planning on solving this issue: https://adamwathan.me/going-full-time-on-tailwind-css/
I guess this means we'll also be able to @apply
classes generated for all variants (also via plugins) 🎉
So in this particular example, @apply
is sort of being used in a way it wasn't intended to be used.
The idea with @apply
is that you use it to mix in existing utilities, simple classes that just do one thing, but in this example it's being used to mix in .btn
which is a component class and has a lot more complexity to it (like the hover state.)
In fact in the current example, it's sort of just a coincidence that @apply .btn
works at all, because we process @apply
rules in a single pass.
That means that this happens to work:
// Input
.foo {
@apply bg-red;
.bar {
@apply foo;
// Output ✅
.foo {
background-color: red;
.bar {
background-color: red;
...but this wouldn't:
// Input
.foo {
@apply bar;
.bar {
@apply bg-red;
// Output ❌
.foo {
@apply bg-red;
.bar {
background-color: red;
Since @apply
is processed in one pass, you can't reliably apply classes that apply other classes, because we don't process them recursively until all @apply
calls are gone. This may change in the future but right now it's by design.
That all said, the plan for making @apply
work for more scenarios will allow you to do what you want eventually, but you'd have to write it like this:
.btn {
@apply cursor-pointer;
@apply font-bold box;
.btn-orange {
@apply bg-orange text-white hover:bg-orange-dark;
input[type="submit"] {
@apply btn btn-orange;
...or alternatively not use Sass, and rely on the nesting support that will be coming to Tailwind itself.
In general I am sort of hesitant to recommend working this way or promise support for using @apply
to apply component classes, because again it's meant to be used only for utilities by design. I want to be very careful avoiding scope-creep here and having what was designed to just be a simple "mix tiny utility classes into bigger component classes" feature become a full-blown mixin system like in Sass or Less. But it may end up that I can comfortably support this workflow depending on how these other improvements I'm making to @apply
change the architecture of the feature, so we'll see.
Until then, since you're already using Sass I would recommend just using regular Sass mixins for what you are trying to do:
@mixin btn {
@apply cursor-pointer;
@apply font-bold box;
@mixin btn-orange {
@apply bg-orange text-white;
&:hover {
@apply bg-orange-dark;
.btn {
@include btn;
.btn-orange {
@include btn-orange;
input[type="submit"] {
@include btn;
@include btn-orange;
I'm going to close this for now as it's not a bug or anything, Tailwind is working as designed in this case, but I'm still planning to explore expanding the scope of @apply
to handle this scenario closer to how the OP expected it to work.