mirror of
https://github.com/tailwindlabs/tailwindcss.git
synced 2025-12-08 21:36:08 +00:00
This PR adds a migration where we detect arbitrary variants and try to upgrade them to built-in variants. For example, if you are using `[[data-visible]]:flex`, we can convert it to `data-visible:flex`. We can also upgrade more advanced examples such as `has-[[data-visible]]:flex` to a compound variant which becomes `has-data-visible:flex`. A table of example migrations: | Before | After | | ------------------------------------------ | ---------------------------------- | | `[[data-visible]]:flex` | `data-visible:flex` | | `[&[data-visible]]:flex` | `data-visible:flex` | | `[[data-visible]&]:flex` | `data-visible:flex` | | `[[data-url*="example"]]:flex` | `data-[url*="example"]:flex` | | `[[data-url$=".com"_i]]:flex` | `data-[url$=".com"_i]:flex` | | `[[data-url$=.com_i]]:flex` | `data-[url$=.com_i]:flex` | | `[&:is([data-visible])]:flex` | `data-visible:flex` | | `has-[[data-visible]]:flex` | `has-data-visible:flex` | | `has-[&:is([data-visible])]:flex` | `has-data-visible:flex` | | `has-[[data-slot=description]]:flex` | `has-data-[slot=description]:flex` | | `has-[&:is([data-slot=description])]:flex` | `has-data-[slot=description]:flex` | | `has-[[aria-visible="true"]]:flex` | `has-aria-visible:flex` | | `has-[[aria-visible]]:flex` | `has-aria-[visible]:flex` | We can also convert combinators from `[&>[data-visible]]:flex` to just `*:data-visible:flex` and `[&_[data-visible]]:flex` to `**:data-visible:flex`. | Before | After | | --- | --- | | `[&>[data-visible]]:flex` | `*:data-visible:flex` | | `[&_>_[data-visible]]:flex` | `*:data-visible:flex` | | `[&_[data-visible]]:flex` | `**:data-visible:flex` | Additionally, if you have complex selectors with `:not()`, we can convert this to a compound `not-*` variant in some cases as well: | Before | After | | --- | --- | | `[&:nth-child(2)]:flex` | `nth-2:flex` | | `[&:not(:nth-child(2))]:flex` | `not-nth-2:flex` | If some of the values in `nth-child(…)` are a bit too complex, then we still try to convert them but to arbitrary values instead. | Before | After | | --- | --- | | `[&:nth-child(-n+3)]:flex` | `nth-[-n+3]:flex` | | `[&:not(:nth-child(-n+3))]:flex` | `not-nth-[-n+3]:flex` | This also implements some optimizations around `even` and `odd`: | Before | After | | --- | --- | | `[&:nth-child(odd)]:flex` | `odd:flex` | | `[&:not(:nth-child(odd))]:flex` | `even:flex` | | `[&:nth-child(even)]:flex` | `even:flex` | | `[&:not(:nth-child(even))]:flex` | `odd:flex` | Some examples that stay as-is: - `has-[&>[data-visible]]:flex` we can't upgrade this one because `has-*` is not a valid variant. - `has-[[data-visible][data-dark]]:flex` we can't upgrade this one because `[data-visible][data-dark]` has to be on the same element. If we convert this to `has-data-visible:has-data-dark:flex` then this condition will be true if an element exists with `data-visible` and another element exists with `data-dark` but we don't guarantee that they are the same element. --- Running this on the Catalyst codebase results in some updates that look like this: <img width="676" alt="image" src="https://github.com/user-attachments/assets/6f0ff21d-5037-440b-9b80-0997ab0c11dd"> <img width="397" alt="image" src="https://github.com/user-attachments/assets/8f0856fa-1709-404a-ac34-7d8c661fa799"> --------- Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
A utility-first CSS framework for rapidly building custom user interfaces.
Documentation
For full documentation, visit tailwindcss.com.
Community
For help, discussion about best practices, or any other conversation that would benefit from being searchable:
Discuss Tailwind CSS on GitHub
For chatting with others using the framework:
Join the Tailwind CSS Discord Server
Contributing
If you're interested in contributing to Tailwind CSS, please read our contributing docs before submitting a pull request.