After the changes in #15201, our Windows CI started to fail. The problem
is that lightningcss now needs to convert `oklch` colors into the
`oklab` space to inline some `color-mix()` functions.
The problem, though, is that this calculation seems to have rounding
differences between macOS, Linux, and Windows. Since we still want to
_define the default color space in `oklch`_ and _use lightningcss as a
post-processor in our unit tests so we have a better coverage of the
output_, this PR attempts to fix the issue by adding a custom vitest
serializer. It will find usages of the `oklab()` function with arguments
that have lots of decimal places (at least 6 decimal places). What it
then does is simply cut off any excess decimal places to truncate the
output to 5 places. E.g.:
```diff
- oklab(62.7955% .224863 .125846 / .75);
+ oklab(62.7955% .22486 .12584 / .75);
```
## Test Plan
I updated the CI workflow file to make all three builds run in CI and
observed that they are now all green again.
<img width="609" alt="Screenshot 2024-11-27 at 14 54 52"
src="https://github.com/user-attachments/assets/73fe6da5-30e3-4fd4-83ea-115b1f1602a6">
This PR throws an error when we notice that an `layer(…)` in an
`@import` or `@media` is incorrect.
This hints the user to ensure that `layer(…)` in an `@import` should be
the first condition. In case of an `@media`, it should be an `@layer …`
instead.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Fixes https://github.com/tailwindlabs/tailwindcss/discussions/15184,
https://github.com/tailwindlabs/tailwindcss/issues/14955
There's a strange bug in Safari < 18 where mixing a color with
`transparent` or with a gray tone, the resulting color looks as if it's
been interpolated through a red-ish color.
Here's the same blue to transparent gradient in Safari 17 using OKLAB
and OKLCH for comparison:
<img width="747" alt="image"
src="https://github.com/user-attachments/assets/1cb09b00-0d84-4284-be34-103726d8af03">
In other browsers, both of these examples look identical.
This bug also shows up when using an opacity modifier right now because
we use `in oklch` in our `color-mix(…)` calls:
<img width="744" alt="image"
src="https://github.com/user-attachments/assets/b029c5f1-0c5c-4119-80ba-dfeabe25927e">
This PR updates all of the affected places in Tailwind to use `in oklab`
instead of `in oklch` which then renders everything as expected in all
browsers.
The big unfortunate change here is changing the default behavior of
gradient utilities like `bg-linear-to-r` to use `in oklab` instead of
`in oklch`. This means you get muddier gradients by default when
creating a gradient between two regular colors (no transparent or gray),
like how they looked in v3:
<img width="740" alt="image"
src="https://github.com/user-attachments/assets/d02e7596-4c99-4ba3-b929-d2db4911c8e9">
This feels worth it though to avoid people getting bitten by this Safari
bug without realizing it, and people can always opt in to using OKLCH
with classes like `bg-linear-to-r/oklch`. The nice thing about making
this opt-in is that no one will opt-in to this when using transparent or
gray because it won't make things look any different/better, and the
only places where it does make things look better _do_ work as expected
in Safari anyways.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This PR fixes an issue where multi-line candidates in Svelte files
couldn't be found as reported in #15148
After digging in, the real culprit seems to be that the reproduction
used tab `\t` characters instead of spaces and we only delimited
explicitly on spaces.
Initially I couldn't reproduce this in an integration test until we
(@thecrypticace and I) realised that `\t` was being used.
## Test plan:
This PR adds an integration test that fails before the fix happens. The
fix itself is easy in the sense that we just use all ascii whitespace
characters instead of just spaces.
Fixes: #15148
Fixes#15146.
This PR updates the `w-*`, `max-w-*`, `min-w-*`, and `basis-*` utilities
to make sure that `--spacing-*` values are preferred over
`--container-*` values when there is a conflict.
Given this theme configuration:
```css
@theme {
--spacing-sm: 8px;
--container-sm: 256px;
}
```
…utilities like `max-w-sm` will use `8px` instead of `256px` after this
change.
Users can still be explicit about the value they want to use if they've
introduced a naming collision like this by using our variable shorthand
like `max-w-(--container-sm)`.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Closes#15160
We need to set browser targets for each browser individually to see
vendor prefixes created for each browser.
Exact values are up for discussion, this first pass is taken from
@adamwathan's comments in
https://github.com/tailwindlabs/tailwindcss/issues/15160
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
Fixes#15144.
Weird bug in Safari that breaks 3D transforms when using registered
custom properties registered with the "<transform-function>" type:
https://bugs.webkit.org/show_bug.cgi?id=283487
Declaring them as just "*" fixes it with no apparent downside since
transitioning these 3D transforms still works, and usually
transitions/animations are the reason you'd type these properties.
Evidence of rotations looking the same in all browsers here:

---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This PR fixes an issue where the `.group` and `.peer` classes didn't get
prefixed if you are using the `prefix(…)` option.
Before this change, `tw:group-hover:flex`, generated:
```css
.tw\\:group-hover\\:flex {
&:is(:where(.group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
But now it generates:
```css
.tw\\:group-hover\\:flex {
&:is(:where(.tw\\:group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
Or as a diff, it might be more clear:
```diff
.tw\\:group-hover\\:flex {
- &:is(:where(.group):hover *) {
+ &:is(:where(.tw\\:group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
Fixes: #15172
Fixes https://github.com/tailwindlabs/tailwindcss/issues/15107.
Previously we were generating `word-break: break-keep` when it should be
`word-break: keep-all`.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Fix#15085
We were relying on Node's printing of errors during build but this
prints the line of code the error occurs on. Since the code is minified
you'd get a really long string of code that wrapped a ton in the console
before the actual error. Now we print errors during build like we do in
watch mode.
This PR ensures that when we inject `layer(…)` into an `@import` that it
always gets inserted as the first param. The `layer(…)` has to come
first by spec.
Input:
```css
@import "./foo" supports(--foo);
```
Before:
```css
@import "./foo" supports(--foo) layer(utilities);
```
After:
```css
@import "./foo" layer(utilities) supports(--foo);
```
Closes#15071
This PR reverts the changes in #15036 which add consistent base styles
for buttons and form controls to Preflight.
While this felt like a good idea (for the reasons explained in that PR),
practically this is just too disruptive of a change for people upgrading
from v3 to v4.
While updating some of our projects to v4 we found ourselves adding
classes to undo styles more often than we expected, and it also felt
inconsistent to have to use a different set of classes to style a link
or a button when we wanted them to look the same.
We also decided it feels a little strange that you could change the
border color of an element without ever specifying that it should have a
border, for example this just feels a little wrong:
```html
<button class="border-blue-500">
```
We also needed to set a default `color-scheme` value for any of this
stuff to work which breaks the ability to use the `color-scheme` meta
tag.
Since this change was a fairly major breaking change and we aren't
feeling much benefit from it, it doesn't feel worth making this change
for v4.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
We weren't resetting the `--tw-space-x-reverse` and
`--tw-space-y-reverse` state in the `space-x/y-{number}` utilities which
broke code assuming that `md:space-x-3` would no longer be reversed.
This PR fixes that.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
These utilities are deprecated (and were removed) but we're brining them
back so they keep working:
- `flex-grow-*`
- `flex-shrink-*`
- `decoration-slice`
- `decoration-clone`
- `overflow-ellipsis`
This PR improves compatibility for named `opacity` theme values. One of
the changes in v4 is that we use the CSS `color-mix()` function to apply
opacity to colors. This, however, is limited to percentage values only:
```css
color: color-mix(in oklch, var(--color-red-500) 50%, transparent);
/* ^^^ */
/* This needs to be a percentage value */
```
In v3, however, it was common to specify custom opacity values as
decimal numbers. That's also what we did in our default config:
6069a81187/stubs/config.full.js (L703-L725)
This PR improves interop with these values by:
1. Converting decimal numbers in the range of `[0, 1]` to their
percentage value equivalent when using the interop layer.
2. Adjusts the codemod that migrates `opacity` theme keys to Tailwind v4
theme variables to include the same conversion.
3. Furthermore, due to the added support of named opacity modifers, we
can also drop theme keys that would now be the default. For example the
following config would not be necessary in v4 as the opacity modifier
would accept the value `50` by default:
```js
module.exports = {
theme: {
opacity: {
50: 0.5
}
}
}
```
## Test Plan
Added a new integration test for the codemod and a unit test for the
interop layer. I also re-ran the codemod on the Commit template and it's
now working as expected (left is v3, right is v4):
<img width="2560" alt="Screenshot 2024-11-21 at 17 25 32"
src="https://github.com/user-attachments/assets/f0c87243-ca80-4c39-ae5e-c1ab48fbe614">
While testing the latest alpha release across Tailwind v3 projects, we
noticed one regression in relation to the default color of `<button>`
elements. In v3, the reset would change the default to `inherit` but in
v4 we would _not include it in the reset snippet inserted by the upgrade
too_.
This PR changes the upgrade snippet to include it:
```diff
/*
In Tailwind CSS v4, basic styles are applied to form elements by default. To
maintain compatibility with v3, the following resets have been added:
*/
@layer base {
input,
textarea,
select,
button {
border: 0px solid;
border-radius: 0;
padding: 0;
+ color: inherit;
background-color: transparent;
}
}
```
This PR also ensures that there's a newline between the two code
snippets.
## Test Plan
### Before

### After
<img width="1354" alt="Screenshot 2024-11-21 at 15 42 58"
src="https://github.com/user-attachments/assets/9a4503fe-683f-4d08-abf2-7dd111ed5428">
This PR makes the candidate parser more strict by not allowing empty
arbitrary values.
Examples that are not allowed anymore:
- `bg-[]` — arbitrary value
- `bg-()` — arbitrary value, var shorthand
- `bg-[length:]` — arbitrary value, with typehint
- `bg-(length:)` — arbitrary value, with typehint, var shorthand
- `bg-red-500/[]` — arbitrary modifier
- `bg-red-500/()` — arbitrary modifier, var shorthand
- `data-[]:flex` — arbitrary value for variant
- `data-():flex` — arbitrary value for variant, var shorthand
- `group-visible/[]:flex` — arbitrary modifier for variant
- `group-visible/():flex` — arbitrary modifier for variant, var
shorthand
If you are trying to trick the parser by injecting some spaces like
this:
- `bg-[_]`
Then that is also not allowed.
This PR updates the default `drop-shadow-*` values to use a single
shadow instead of multiple shadows.
This ensures that the usage with `drop-shadow(var(--drop-shadow-xl))` is
correct because the `drop-shadow(…)` needs to encode a single drop
shadow.
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR introduces consistent base styles for buttons and form controls
in Tailwind CSS v4.
## Motivation
In v3, form elements lack default styles, which can be
confusing—especially when certain elements, like a text input without a
placeholder or value, are rendered completely invisible on the page.
The goal of this change is to provide reasonable default styles for
buttons, inputs, selects, and textareas that are (mostly) consistent
across all browsers while remaining easy to customize with your own
styles.
This improvement should make Tailwind more accessible for developers new
to the framework and more convenient in scenarios where you need to
quickly create demos (e.g., using Tailwind Play).
## Light and dark mode support
These styles support both light and dark mode, achieved using the
`light-dark()` CSS function. While browser support for this function is
still somewhat limited, Lightning CSS transpiles it to a CSS
variable-based approach that works in older browsers.
For this approach to function correctly, a default `color-scheme` must
be set in your CSS (as explained in [the Lightning CSS
documentation](https://lightningcss.dev/transpilation.html#light-dark()-color-function)).
This PR addresses this requirement by setting the `color-scheme` to
`light` on the `html` element in Preflight.
<img width="1712" alt="image"
src="https://github.com/user-attachments/assets/dba56368-1427-47b3-9419-7c2f6313a944">
<img width="1709" alt="image"
src="https://github.com/user-attachments/assets/3d84fcd2-9606-4626-8e03-164a1dce9018">
## Breaking changes
While we don’t expect these changes to significantly impact v3 users
upgrading to v4, there may be minor differences for those relying on the
simpler v3 styles.
For example, Preflight now applies a `border-radius` to buttons and form
controls. If you weren’t explicitly setting the border radius to `0` in
your project, you’ll need to do so to restore the previous look.
Thankfully, reverting to the v3 styles is straightforward—just add the
following reset to your CSS:
```css
@layer base {
input,
textarea,
select,
button {
border: 0px solid;
border-radius: 0;
padding: 0;
background-color: transparent;
}
}
```
It’s worth noting that this reset doesn't touch the
`::file-selector-button` styles that were added in this PR. This is
because it's not possible to reliably "undo" these styles and restore
the original user-agent styles (which is what was used in v3), as these
are different in each browser. However, these new styles actually match
the defaults in most browsers pretty closely, so hopefully this just
won't be an issue.
## Codemod
This PR includes a codemod that automatically inserts the above
mentioned v3 reset to help avoid breaking changes during the upgrade.
The codemod will insert the following CSS:
```css
/*
In Tailwind CSS v4, basic styles are applied to form elements by default. To
maintain compatibility with v3, the following resets have been added:
*/
@layer base {
input,
textarea,
select,
button {
border: 0px solid;
border-radius: 0;
padding: 0;
background-color: transparent;
}
}
```
## Testing
These changes have been tested across a wide range of browsers,
including Chrome, Safari, Firefox, Edge, and Opera on macOS and Windows,
as well as Safari, Chrome, Firefox, and several lesser-known browsers on
iOS and Android.
However, some quirks still exist in certain mobile browsers, such as iOS
Safari, which adds too much bottom padding below date and time inputs:
<img width="1548" alt="Screenshot 2024-11-20 at 3 57 20 PM"
src="https://github.com/user-attachments/assets/507c7724-ac41-4634-a2b3-61ac4917ebce">
The only reliable way to address these issues is by applying
`appearance: none` to these form controls. However, this felt too
opinionated for Preflight, so we’ve opted to leave such adjustments to
user-land implementations.
---------
Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Closes#15050
In Tailwind CSS v4 Alpha 31 we changed how we scan template files. This
changes included a new folder-dependency that is emitted for the `base`
directory, so we can listen for new files being added as part of the
postcss dependency.
In our testing, this worked fine with the Next.js integration meaning a
new file in the project root would be picked up by Oxide and we could
update the CSS files accordingly.
This change is now, however, causing an issue. With Next.js 15 **and
with a custom `distDir` configured**, the postcss build, that will write
into the `distDir`, will cause another postcss run to be triggered,
starting an endless loop (regardless of wether or not the `distDir` was
also part of your gitignore list).
This PR now changes the postcss client to not emit the base directory as
a dependency to revert this changes. This does mean that new files and
folders created _directly in the project root_ will require a restart of
the Next.js server again (just like it did in Alpha 31 and before) for
now.
## Test Plan
Next 15 does not seem to run in our current integration test setup (for
some reason the server does not close correctly and it will fail on the
cleanup step), so this change was tested manually:
- First, clone the [templates
repo](https://github.com/philipp-spiess/tailwindcss-playgrounds) I use
for third party frameworks
- Then, do a full build in the parent repo `tailwindcss` via `pnpm
build`
- Now, install the local tarballs in the `tailwindcss-playgrounds` repo
via `pnpm install`
With this setup I have tested changes to a template file (that causes
new utilities to be added) and the CSS file (that will rebuild properly)
across both `pnpm dev` and `pnpm dev --turbo`. Furthermore integration
tests assert it still works in Next 14 like it did before:
https://github.com/user-attachments/assets/b0ccb3dd-d090-4e4c-97c5-74129a2789be
One thing to make sure of is to include the new `distDir` into the
`.gitignore` file as well, otherwise we will scrape it for changes which
inherently causes an endless loop issue again.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
While testing the codemods on some projects, I noticed some issues with
the migration to the new `in-*` variant.
One such example is that we checked for `&` at the end, instead of ` &`
(the whitespace is significant).
This meant that `[figure>&]:my-0` was converted to `in-[figure>]:my-0`
which is wrong. In this case, we want to keep it as `[figure>&]:my-0`.
Additionally this PR brings back the migration from `group-[]:flex` to
`in-[.group]:flex`. If you are using a prefix, then `group-[]:tw-flex`
is migrated to `tw:in-[.tw\:group]:flex`.
Last but not least, this does some internal refactors to group
migrations logically together.
This PR fixes an issue where the Tailwind root file detection was wrong.
Whenever a CSS file contains any of the `@tailwind` directives or an
`@import` to any of the Tailwind files, the file is considered a
Tailwind root file.
If multiple CSS files are part of the same tree, then we make the
nearest common parent the root file.
This root file will be the file where we add `@config` and/or inject
other changes during the migration process.
However, if your folder structure looked like this:
```css
/* index.css */
@import "./base.css";
@import "./typography.css";
@import "tailwindcss/components"; /* This makes index.css a root file */
@import "./utilities.css";
/* base.css */
@tailwind base; /* This makes base.css a root file */
/* utilities.css */
@tailwind utilities; /* This makes utilities.css a root file */
```
Then we computed that `index.css` nad `base.css` were considered root
files even though they belong to the same tree (because `base.css` is
imported by `index.css`).
This PR fixes that behaviour by essentially being less smart, and just
checking again if any sheets are part of the same tree.
# Test plan:
Added an integration test that covers this scenario and fails before the
fix.
Also ran it on our tailwindcss.com codebase.
| Before | After |
| --- | --- |
| <img width="1072" alt="image"
src="https://github.com/user-attachments/assets/8ee99a59-335e-4221-b368-a8cd81e85191">
| <img width="1072" alt="image"
src="https://github.com/user-attachments/assets/fe5acae4-d3fc-43a4-bd31-eee768a3a6a5">
|
(Yes, I know the migration still fails, but that's a different issue.)
If you have a PostCSS config file, that is not simple (has functions,
requires, ...). In that case we don't migrate the PostCSS file. Because
we don't migrate, the `didMigrate` is still false and we continue with
the next migration.
The issue here is that there are 2 states encoded in the same variable
and they should be two separate variables because there is a difference
between:
1. Not finding a file at all
2. Finding a file, but not migrating it
Before this change, the output looks like this if you have a complex
PostCSS file:
```
│ Migrating PostCSS configuration…
│ The PostCSS config contains dynamic JavaScript and can not be automatically migrated.
│ No PostCSS config found, skipping migration.
```
After this change, the output looks like this:
```
│ Migrating PostCSS configuration…
│ ↳ The PostCSS config contains dynamic JavaScript and can not be automatically migrated.
```
Also updated the output to include `↳ ` to be consistent with the other
logs.
This fixes the negative versions of rotate:
`-rotate-y-*`, `-rotate-x-*`, and `-rotate-z-*`
They were producing CSS like `--tw-rotate-x: calc(rotateX(Xdeg) * -1)`
instead of `--tw-rotate-x: rotateX(calc(Xdeg * -1))`. This fixes all of
those. The skew utilities have a similar structure but were already
handled correctly.
This PR updates the `jiti` dependency we use for plugin loading to the
latest stable release.
## Test Plan
This was relying on integration tests which contains example of
TypeScript configs. It's also rebased to include the new examples from
https://github.com/tailwindlabs/tailwindcss/pull/15041.
This PR uses the `enhanced-resolve` instead of
`createRequire(…).resolve` which improves the usability when running the
upgrade tool locally using Bun.
While testing, we also noticed that it is not possible to use a
`cjs`-only plugin inside of an `esm` project. It was also not possible
to use an `esm`-only plugin inside of a `cjs` project.
# Test plan
We added integration tests in both the CLI (the CLI is an mjs project)
and in the PostCSS (where we can configure a `cjs` and `esm` PostCSS
config) integration tests where we created an `esm` and `cjs` based
project with 4 plugins (`cjs`-only, `esm`-only, and TypeScript based
plugins: `cts`-only and `mts`-only).
Closes#15012
We do not have replacements for these plugins _just yet_. In order to
increase compatibility with setups that rely on some of these legacy
plugins, this PR bundles `@tailwindcss/forms`,
`@tailwindcss/typography`, and `@tailwindcss/aspect-ratio` (after
https://github.com/tailwindlabs/tailwindcss/pull/15029) with the
standalone build now.
In comparison to v3, this omits the `@tailwindcss/container-queries`
plugin since is not a first-party feature of Tailwind CSS v4.
## Test Plan
Added an integration test. I also tested this by running the standalone
binary in a temporary folder with as simple input css:
```css
@import "tailwindcss";
@plugin "@tailwindcss/typography";
```
This implements backwards compatibility for colors that use the old
`<alpha-value>` feature from v3. We can do this by replacing
`<alpha-value>` with `1` because we use `color-mix` to actually apply
opacity modifiers in v4.
In some local testing we ran the `@tailwindcss/upgrade` command twice in
a row. It would be great to get some feedback that this is not working,
so this PR now checks if it can resolve the installed version of
`tailwindcss` and if it can, it requires it to be < 4 (you can bypass
this check with `--force`).
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR adds support for complex `addUtilities()` configuration objects
that use child combinators and other features.
For example, in v3 it was possible to add a utility that changes the
behavior of all children of the utility class node by doing something
like this:
```ts
addUtilities({
'.red-children > *': {
color: 'red',
},
});
```
This is a pattern that was used by first-party plugins like
`@tailwindcss/aspect-ratio` but that we never made working in v4, since
it requires parsing the selector and properly extracting all utility
candidates.
While working on the codemod that can transform `@layer utilities`
scoped declarations like the above, we found out a pretty neat
heuristics on how to migrate these cases. We're basically finding all
class selectors and replace them with `&`. Then we create a nested CSS
structure like this:
```css
.red-children {
& > * {
color: red;
}
}
```
Due to first party support for nesting, this works as expected in v4.
## Test Plan
We added unit tests to ensure the rewriting works in some edge cases.
Furthermore we added an integration test running the
`@tailwindcss/aspect-ratio` plugin. We've also installed the tarballs in
the Remix example from the
[playgrounds](https://github.com/philipp-spiess/tailwindcss-playgrounds)
and ensure we can use the `@tailwindcss/aspect-ratio` plugin just like
we could in v3:
<img width="2560" alt="Screenshot 2024-11-18 at 13 44 52"
src="https://github.com/user-attachments/assets/31889131-fad0-4c37-b574-cfac2b99f786">
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This PR improves the discoverability of Tailwind config files when we
are trying to link them to your CSS files.
When you have multiple "root" CSS files in your project, and if they
don't include an `@config` directive, then we tried to find the Tailwind
config file in your current working directory.
This means that if you run the upgrade command from the root of your
project, and you have a nested folder with a separate Tailwind setup,
then the nested CSS file would link to the root Tailwind config file.
Visually, you can think of it like this:
```
.
├── admin
│ ├── src
│ │ └── styles
│ │ └── index.css <-- This will be linked to (1)
│ └── tailwind.config.js (2)
├── src
│ └── styles
│ └── index.css <-- This will be linked to (1)
└── tailwind.config.js (1)
```
If you run the upgrade command from the root of your project, then the
`/src/styles/index.css` will be linked to `/tailwind.config.js` which is
what we expect.
But `/admin/src/styles/index.css` will _also_ be linked to
`/tailwind.config.js`
With this PR we improve this behavior by looking at the CSS file, and
crawling up the parent tree. This mens that the new behavior looks like
this:
```
.
├── admin
│ ├── src
│ │ └── styles
│ │ └── index.css <-- This will be linked to (2)
│ └── tailwind.config.js (2)
├── src
│ └── styles
│ └── index.css <-- This will be linked to (1)
└── tailwind.config.js (1)
```
Now `/src/styles/index.css` will be linked to `/tailwind.config.js`, and
`/admin/src/styles/index.css` will be linked to
`/admin/tailwind.config.js`.
When we discover the Tailwind config file, we will also print a message
to the user to let them know which CSS file is linked to which Tailwind
config file.
This should be a safe improvement because if your Tailwind config file
had a different name, or if it lived in a sibling folder then Tailwind
wouldn't find it either and you already required a `@config "…";`
directive in your CSS file to point to the correct file.
In the unlikely event that it turns out that 2 (or more) CSS files
resolve to the same to the same Tailwind config file, then an upgrade
might not be safe and some manual intervention might be needed. In this
case, we will show a warning about this.
<img width="1552" alt="image"
src="https://github.com/user-attachments/assets/7a1ad11d-18c5-4b7d-9a02-14f0116ae955">
Test plan:
---
- Added an integration test that properly links the nearest Tailwind
config file by looking up the tree
- Added an integration test that resolves 2 or more CSS files to the
same config file, resulting in an error where manual intervention is
needed
- Ran it on the Tailwind UI codebase
Running this on Tailwind UI's codebase it looks like this:
<img width="1552" alt="image"
src="https://github.com/user-attachments/assets/21785428-5e0d-47f7-80ec-dab497f58784">
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
This PR adds a new `in-*` variant that allows you to apply utilities
when you are in a certain selector.
While doing research for codemods, we notice that some people use
`group-[]:flex` (yep, the arbitrary value is empty…). The idea behind is
that people want to know if you are in a `.group` or not.
Similarly, some people use `group-[]/name:flex` to know when you are in
a `.group/name` class or not.
This new `in-*` variant allows you to do that without any hacks.
If you want to check whether you are inside of a `p` tag, then you can
write `in-[p]:flex`. If you want to check that you are inside of a
`.group`, you can write `in-[.group]`.
This variant is also a compound variant, which means that you can write
`in-data-visible:flex` which generates the following CSS:
```css
:where([data-visible]) .in-data-visible\:flex {
display: flex;
}
```
This variant also compounds with `not-*`, for example:
`not-in-[.group]:flex`.
Additionally, this PR also includes a codemod to convert `group-[]:flex`
to `in-[.group]:flex`.
---
This was proposed before for v3 in #13912
---------
Co-authored-by: Eloy Espinaco <eloyesp@gmail.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>