Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[v4] variants are not applied to custom classes in utilities layer #14058

Closed
sntran opened this issue Jul 25, 2024 · 3 comments
Closed

[v4] variants are not applied to custom classes in utilities layer #14058

sntran opened this issue Jul 25, 2024 · 3 comments

Comments

@sntran
Copy link

sntran commented Jul 25, 2024

What version of Tailwind CSS are you using?

v4.0.0-alpha.17

What build tool (or framework if it abstracts the build tool) are you using?

@tailwindcss/[email protected]

What version of Node.js are you using?

v20.12.2

What browser are you using?

Chrome version 126.0.6478.127 (Official Build) (arm64)

What operating system are you using?

macOS 14.5 (23F79)

Reproduction

@import "tailwindcss";

@layer utilities {
  .foobar {
    font-weight: bold;
  }
}
<h1 class="md:foobar before:foobar">Bold</h1>

Describe your issue

I would expect the following style generated, because .foobar is within @layer directive, and should be able to be used with modifiers, according to docs.

@media (width >= 768px) {
    .md\:foobar {
        font-weight: 700;
    }
}

But there is not. Same with before:foobar.

@sntran
Copy link
Author

sntran commented Jul 25, 2024

I think this is related to #14044. Not sure why the old logic (all utilities in @layer directive can have all modifiers) could not be used but we have to use the new @utility directive instead.

@adamwathan
Copy link
Member

Hey! Yeah this is one of the changes we need to make for v4 because @layer is a real CSS feature now, which wasn't the case when we added it in v3.

In v3, @layer utilities had two side effects:

  • Any code within this block would only be included in your CSS if those classes were actually used
  • Any classes could automatically be used with variants like hover:*, focus:*, etc.

I don't want to hijack real CSS features and change their behavior in special Tailwind-specific ways, so we need a new API for this in v4. You should be able to use regular CSS layers in your code without surprising unexpected side effects.

One of the reasons we're going with @utility my-utility {... } is because you could do stuff like this in v3 which led to an enormous amount of internal complexity:

@layer utilities {
  h2 > .foo + .bar {
    font-weight: bold;
    font-size: 20px;
  }
}

With that rule, we had to make lg:foo work and lg:bar, and handle all these weird permutations of things that could happen because the selector contained multiple classes.

In the v4 API, you're sort of forced to tell Tailwind what the actual "utility" is, and can only pick one:

@utility foo {
  h2 > & + .bar {
    font-weight: bold;
    font-size: 20px;
  }
}

Now we only have to make lg:foo work, which is much more consistent with how built-in utilities in Tailwind work — a utility is a single class that produces some CSS (which might contain nested rules), not a whole selector.

We're going to work on some code mod tooling in the coming months to try and make this migration as simple as possible though either way 👍

@sntran
Copy link
Author

sntran commented Jul 30, 2024

Thanks for taking the time to answer! However, I'm still skeptical that the new v4 API is better.

In v3, @layer utilities had two side effects:

  • Any code within this block would only be included in your CSS if those classes were actually used
  • Any classes could automatically be used with variants like hover:*, focus:*, etc.

I would argue that those side effects were why most of us put CSS into that utilities layer so they could be used with all variants, only when they were actually used. Otherwise, we could just leave the CSS outside the layer and it would be the same result.

I don't want to hijack real CSS features and change their behavior in special Tailwind-specific ways, so we need a new API for this in v4. You should be able to use regular CSS layers in your code without surprising unexpected side effects.

But the new API would not work as regular CSS either. And neither @apply. So Tailwind-based CSS would not really work without being complied by Tailwind. We could have CSS in true layers, but they would not be useful without variants.

One of the reasons we're going with @utility my-utility {... } is because you could do stuff like this in v3 which led to an enormous amount of internal complexity:

@layer utilities {
  h2 > .foo + .bar {
    font-weight: bold;
    font-size: 20px;
  }
}

That is definitely bad and not considered an utility. Maybe instead of trying to make that work, Tailwind could throw an error. Tailwind has a lot of conventions, and requiring utilities to be single class is not big of an ask.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants