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] "hidden" is not the last display utility anymore #15884

Open
iquito opened this issue Jan 26, 2025 · 8 comments
Open

[v4] "hidden" is not the last display utility anymore #15884

iquito opened this issue Jan 26, 2025 · 8 comments

Comments

@iquito
Copy link

iquito commented Jan 26, 2025

What version of Tailwind CSS are you using?

v4.0

Reproduction URL

https://play.tailwindcss.com/1XH8TJa6s3 for v4 (element is shown)
https://play.tailwindcss.com/Ajm578zcYz for v3.4.15 (element is not shown)

Describe your issue

The order of the display utilities has slightly changed in v4, putting hidden somewhere in the middle of these utilities by default (after block, but before inline-block or inline-flex), where in v3.4 it was at the end of all the display utilities. I have used TailwindCSS often like this:

<div class="inline-block hidden">Some text that is either displayed as inline-block or hidden</div>

Then I remove or re-add the hidden class with Javascript, which worked fine in v3. In v4 this does not work with inline-block anymore (because inline-block comes after hidden in the generated CSS), while it does work with block (as it comes before hidden). I found the behavior better in v3.4, where hidden was assumed to be the preferred/overriding value (if set) of all the display utilities and comes last in the definitions. I could imagine many people used hidden in this way and will find the new order surprising.

@wongjn
Copy link
Contributor

wongjn commented Jan 26, 2025

You shouldn't ever have two utilities that apply the same CSS property in the same context, because -as you have found - order is not guaranteed. Consider toggling between them.

@iquito
Copy link
Author

iquito commented Jan 26, 2025

With any other CSS property I would agree with you, but with hidden it is a convenient way to hide an element that could have any other display utility class at the moment. If you want to toggle, you would need to keep track of the original display class, instead of just being able to add or remove hidden (and not knowing anything about the element itself or how it is being displayed otherwise), so I think being able to add hidden and it coming last in the CSS definitions has some value, and with past TailwindCSS versions this has been the case.

As I am already using v4 for my project, I have "solved" this problem with a zero-width-breakpoint-version of hidden, but as more people switch to v4 I could imagine that this could cause some subtle breaks in applications that assumed the same thing as me and thought Tailwind would keep hidden as the last display utility class.

@wongjn
Copy link
Contributor

wongjn commented Jan 26, 2025

You could use the hidden attribute as an alternative - if you are using Tailwind's Preflight, it would take precendence over any other display utility.

@iquito
Copy link
Author

iquito commented Jan 26, 2025

Interesting, thanks for the tip, that might be a good alternative.

@philipp-spiess
Copy link
Member

@iquito Were you able to make it work with the hidden attribute?

@iquito
Copy link
Author

iquito commented Jan 28, 2025

@philipp-spiess Yes, the hidden attribute is a good way to solve it and maybe some additional documentation about it would be helpful (so far I didn't find anything about it in the docs, it is also not mentioned in the preflight explanation).

It was quite a bit of work though even in my not-so-huge application, so changing the order of the hidden class to come last in the CSS like in v3 would avoid this possible BC break for applications doing something similar without having to do a lot of changes, therefore I still think it would make sense to avoid this pain point for other users upgrading to v4 while also adjusting the docs to promote using the hidden attribute for this kind of behavior from now on.

@finkrer
Copy link

finkrer commented Jan 30, 2025

My Button component is inline-flex inside. I used hidden on the component to hide it conditionally. The fact that it is technically the same property... well, let's just say Tailwind class names, it being inside of the component, and it working just fine made it easy to forget about that.

Now, first, this is a breaking change, and I honestly don't know where it might pop up where I haven't noticed it yet.

Second, how do I do this now? Or even, how was I supposed to do it before? The hidden attribute is cool, but what about lg:hidden? Using the Tailwind breakpoints was the whole reason to use hidden the utility class to hide stuff. Do I have to use JS to get the screen width, compare it to a breakpoint, and set the hidden attribute accordingly? Nah, that's too much work.

I guess from now on it's lg:hidden!. But if you need to hide for the smaller breakpoint, it's hidden! lg:block!. Not pretty, still better than JS though.

@RobinMalfait
Copy link
Member

@finkrer the problem only exists if you set the inline-flex and hidden class at the same time unconditionally. If you have inline-flex lg:hidden that still works as expected because they don't have the same "specificity" in this case.

E.g.: https://play.tailwindcss.com/dvYE6VFc7T

This kind of issue already existed in v3, especially because unfortunately class order in the HTML doesn't matter.

<div class="text-red-500 text-blue-500"></div>
<div class="text-blue-500 text-red-500"></div>

E.g.: https://play.tailwindcss.com/d2zsKyorBH

If you use the VSCode Intellisense plugin then you should see some squiggles (as you can see in the Tailwind Play link). If you use the prettier plugin, then we sort the classes to be consistent and to reduce the amount of potential issues you run into.

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

5 participants