Commit graph

351 commits

Author SHA1 Message Date
Jonathan Reinink
2cbc915193
Rename --aspect-ratio-* theme key to --aspect-* (#15365)
This PR renames the `--aspect-ratio` theme key to `--aspect`. This is to
match what we've done with other theme keys where they match the utility
names, like `--ease` and `--leading`.

```diff
  @theme {
-   --aspect-ratio-retro: 4 / 3;
+   --aspect-retro: 4 / 3;
  }
```

Additionally, I've also converted the existing `aspect-video` static
utility to a theme value. This will allow people to override this
utility in their own projects—something that's not possible with static
utilities. This change feels appropriate since the video aspect ratio is
subjective, unlike other static utilities like `aspect-square`.

```css
@theme {
  --aspect-video: 4 / 3; /* N64 baby! */
}
```
2024-12-10 14:33:20 -05:00
Jordan Pittman
ea9d700cf9
Optimize AST before printing for IntelliSense (#15347)
We changed how AST printing worked recently but forgot to update this.
Which causes us to print properties with a value of `undefined` in
Tailwind Play, Tailwind CSS IntelliSense, and our Language Server
(oops).

This PR fixes this by optimizing the AST before printing (which is what
toCss did previously)
2024-12-09 12:44:42 -05:00
Philipp Spiess
1566c3a17b
Suggest shadow-none (#15342)
Noticed a missing `shadow-none` completion while finally starting the
work to migrate my personal blog to Tailwind, lol.
2024-12-09 12:32:50 +01:00
Philipp Spiess
a7ebc9cda1
Expose flattenColorPalette (#15318)
Resolves #15315 

It looks like we implemented this in Core but forgot to expose it from
the distributed package (the references are only used for testing
plugins internally right now). This exposes `flattenColorPalette` under
the old import path of `tailwindcss/lib/util/flattenColorPalette`.

## Test Plan

Added the following plugin to the Vite example and ensured it works as
expected:

```ts
import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette'
import plugin from 'tailwindcss/plugin'

export default plugin(({ matchUtilities, theme }) => {
  matchUtilities(
    {
      'hover-bg': (value) => {
        return {
          '&:hover': {
            backgroundColor: value,
          },
        }
      },
    },
    { values: flattenColorPalette(theme('colors')) },
  )
})
```

<img width="462" alt="Screenshot 2024-12-06 at 11 47 44"
src="https://github.com/user-attachments/assets/11163390-053e-4c6e-8cb9-ae67184ad594">
2024-12-09 11:33:19 +01:00
Jordan Pittman
3d0b86c7d2
Prepare v4.0.0-beta.6 release (#15325) 2024-12-06 14:32:21 -05:00
Philipp Spiess
1238d07ca2
Reference imports should not generate utilities (#15307)
We noticed an issue where the new `@import "…" reference` syntax was not
throwing away `@tailwind` declarations, effectively causing you to
create utility classes whenever you used this feature.

This is especially noticed in setups with very strict compilers like
Svelte.

## Test Plan

### Before

<img width="1142" alt="Screenshot 2024-12-05 at 11 56 00"
src="https://github.com/user-attachments/assets/546f0eb3-4401-48c9-9268-76992e899226">

### After

<img width="2560" alt="Screenshot 2024-12-05 at 12 27 30"
src="https://github.com/user-attachments/assets/16732000-e02c-49bc-ac6f-91da0cfcc7e8">
2024-12-05 16:18:06 +01:00
Philipp Spiess
85da88f851
Prepare v4.0.0-beta.5 (#15285)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-12-04 16:28:16 +01:00
Robin Malfait
408fa99849
Use AST transformations in @tailwindcss/postcss (#15297)
This PR improves the `@tailwindcss/postcss` integration by using direct
AST transformations between our own AST and PostCSS's AST. This allows
us to skip a step where we convert our AST into a string, then parse it
back into a PostCSS AST.

The only downside is that we still have to print the AST into a string
if we want to optimize the CSS using Lightning CSS. Luckily this only
happens in production (`NODE_ENV=production`).

This also introduces a new private `compileAst` API, that allows us to
accept an AST as the input. This allows us to skip the PostCSS AST ->
string -> parse into our own AST step.

To summarize:

Instead of:
- Input: `PostCSS AST` -> `.toString()` -> `CSS.parse(…)` -> `Tailwind
CSS AST`
- Output: `Tailwind CSS AST` -> `toCSS(ast)` -> `postcss.parse(…)` ->
`PostCSS AST`

We will now do this instead:
- Input: `PostCSS AST` -> `transform(…)` -> `Tailwind CSS AST`
- Output: `Tailwind CSS AST` -> `transform(…)` -> `PostCSS AST`


---

Running this on Catalyst, the time spent in the `@tailwindcss/postcss`
looks like this:
- Before: median time per run: 19.407687 ms
- After: median time per run: 11.8796455 ms

This is tested on Catalyst which roughly generates ~208kb worth of CSS
in dev mode.

While it's not a lot, skipping the stringification and parsing seems to
improve this step by ~40%.

Note: these times exclude scanning the actual candidates and only time
the work needed for parsing/stringifying the CSS from and into ASTs. The
actual numbers are a bit higher because of the Oxide scanner reading
files from disk. But since that part is going to be there no matter
what, it's not fair to include it in this benchmark.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-12-04 15:43:59 +01:00
Jordan Pittman
536e11895e
Add some missing suggestions in IntelliSense (#15288)
When we renamed the theme keys this got missed

Theme keys like `--font-sans` will result in suggestions for `font-sans`
again
2024-12-03 19:11:30 -05:00
Philipp Spiess
78f5b087d4
Add @import "…" reference (#15228)
Closes #15219

This PR adds a new feature, `@import "…" reference` that can be used to
load Tailwind CSS configuration files without adding any style rules to
the CSS.

The idea is that you can use this in combination with your Tailwind CSS
root file when you need to have access to your full CSS config outside
of the main stylesheet. A common example is for Vue, Svelte, or CSS
modules:

```css
@import "./tailwind.css" reference;

.link {
  @apply underline;
}
```

Importing a file as a reference will convert all `@theme` block to be
`reference`, so no CSS variables will be emitted. Furthermore it will
strip out all custom styles from the stylesheet. Furthermore plugins
registered via `@plugin` or `@config` inside reference-mode files will
not add any content to the CSS file via `addBase()`.

## Test Plan

Added unit test for when we handle the import resolution and when
`postcss-import` does it outside of Tailwind CSS. I also changed the
Svelte and Vue integration tests to use this new syntax to ensure it
works end to end.

---------

Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-12-03 14:15:24 +01:00
Adam Wathan
e9426d01a6
Use correct values for float-start/end and clear-start/end (#15261)
This PR fixes the `float-start/end` and `clear-start/end` utilities to
use `inline-start` and `inline-end` instead of `start` and `end`, which
aren't valid values.

Fixes #15255.

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-12-02 09:34:13 -05:00
Robin Malfait
973650624d
Prepare v4.0.0-beta.4 (#15245) 2024-11-29 17:18:42 +01:00
Robin Malfait
99b73ee368
Improve performance of @tailwindcss/postcss and @tailwindcss/vite (#15226)
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.

The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.

E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.

That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.

To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)

The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.

---

Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-29 10:59:29 -05:00
Philipp Spiess
6abd8086c3 Prepare v4.0.0-beta.3 (#15217)
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-27 18:25:37 +01:00
Adam Wathan
a1f78a2b34
Don't register properties with types unless necessary (#15215)
This PR updates many of our `@property` rules to use `syntax: "*"`
instead of a specific type.

Registering custom properties with types triggers all sorts of obscure
edge-case bugs in different browsers (mostly Safari, sometimes Firefox),
but using `"*"` always seems to work. So unless we know we actually need
to animate a custom property, it's safer to register is as `"*"`.

Many of the places our custom properties are used are already inherently
animatable (like the `translate`, `scale`, and `transform`) even when
the underlying properties are not typed, so removing types for things
like `--tw-scale-x` doesn't actually stop the `scale-*` utilities from
being animateable.

I've also updated the `--tw-gradient-from/via/to-position` properties to
use `<length-percentage>` instead of `<length> | <percentage>` because
for some reason I don't understand, only `<length-percentage>` works
correctly when using `calc(…)` in arbitrary values.

Fixes https://github.com/tailwindlabs/tailwindcss/issues/15188,
https://github.com/tailwindlabs/tailwindcss/issues/14277.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-27 11:47:27 -05:00
Adam Wathan
aa15964b28
Use unitless line-heights for font-size variables (#15216)
Safari has an [insane
bug](https://github.com/tailwindlabs/tailwindcss/issues/15196) where if
you register custom properties for gradient colors using the `"<color>"`
type, you attempt to transition a gradient on an element, _and_ you set
a font-size and line-height on that element that point to CSS variables
defined using `rem` units, the element size changes and shifts the
layout while the transition is happening:


https://github.com/user-attachments/assets/46eefccf-8a12-4751-8a44-54e48c54cd06

This bug goes away if you use anything other than `rem` units for the
line-height. So this PR changes all of our variables like
`--text-3xl--line-height` to use unitless relative line-height values
instead of fixed line-height values to workaround this bug. Not my
favorite change but pretty low impact because you likely aren't going to
reference those variables for much anyways.

If Safari ever fixes this bug (which is still present as of Safari 18),
it would be nice to swap these back to what they were.

Fixes #15196.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-27 11:39:04 -05:00
Philipp Spiess
bfcc144798
Reduce precision of oklab() arguments in test snapshots (#15210)
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">
2024-11-27 11:06:19 -05:00
Robin Malfait
6aac3cbd69
Throw when layer(…) in @import is in the incorrect spot (#15109)
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>
2024-11-27 11:33:25 +00:00
Adam Wathan
961e8da8fd
Use oklab instead of oklch for color-mix(…) and gradients (#15201)
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>
2024-11-27 06:18:31 -05:00
Adam Wathan
a022905279
Ensure --spacing-* variables take precedence over --container-* variables (#15180)
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>
2024-11-26 09:45:16 -05:00
Philipp Spiess
cb518f4623
Set browser targets for iOS Safari, Firefox, and Chrome (#15166)
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>
2024-11-26 11:22:12 +00:00
Adam Wathan
8217b5ccce
Declare transform properties with "*" syntax instead of "<transform-function>" (#15179)
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:


![image](https://github.com/user-attachments/assets/bcaa6145-e047-4e26-8384-c5599b647cf9)

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-25 21:20:54 -05:00
Robin Malfait
98359bea94
Ensure .group and .peer are prefixed when using the prefix(…) option (#15174)
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
2024-11-25 16:00:21 -05:00
Jordan Pittman
bd43d63df2
Prepare v4.0.0-beta.2 release (#15104)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-22 11:17:21 -05:00
Adam Wathan
0c7088ed5d
Generate the correct CSS for the break-keep utility (#15108)
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>
2024-11-22 10:40:23 -05:00
Jonathan Reinink
dad9ac6209
Revert new default form styles (#15100)
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>
2024-11-22 08:55:05 -05:00
Jordan Pittman
92bf26ba1a
Reset reverse state in space-x/y-* and divide-x/y-* (#15094)
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>
2024-11-22 08:52:11 -05:00
Adam Wathan
c5a0b5481f
Use configured letter-spacing values for custom font-size utilities (#15099)
Fixes https://github.com/tailwindlabs/tailwindcss/issues/15096.

We were mistakenly reading from the `--tracking` sub-property but should
be reading from `--letter-spacing`.

To test this I copied the reproduction from the issue into our Vite
playground and made sure the custom letter-spacing was being applied as
expected:

<img width="1443" alt="image"
src="https://github.com/user-attachments/assets/bfc9ca23-bfc7-40d4-aec0-d3e715312eac">

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-22 08:49:22 -05:00
Jordan Pittman
5e4f565fe4
Prepare v4.0.0-beta.1 release (#15070) 2024-11-21 13:20:30 -05:00
Jordan Pittman
0c97a5b880
Bring back some deprecated utilities (#15069)
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`
2024-11-21 13:09:41 -05:00
Philipp Spiess
6c85327908
Convert opacity keys to percentage values (#15067)
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">
2024-11-21 19:06:58 +01:00
Robin Malfait
11dce5af48
v4.0.0-alpha.36 (#15062)
Prepare v4.0.0-alpha.36
2024-11-21 14:20:56 +01:00
Robin Malfait
3cf5c2df79
Disallow empty arbitrary values (#15055)
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.
2024-11-21 13:47:13 +01:00
Jordan Pittman
4f63a5a9e0
Inline theme values in drop-shadow (#15056)
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>
2024-11-21 13:13:38 +01:00
Philipp Spiess
fcf948f8c8
Add consistent base styles for buttons and form controls (#15036)
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>
2024-11-21 11:21:31 +01:00
Robin Malfait
8b098fc83d
Prepare v4.0.0-alpha.35 release (#15052) 2024-11-20 11:12:32 +00:00
Robin Malfait
85dc3db633
Add new transition-discrete and transition-normal utilities (#15051)
This PR adds two new utilities for the `transition-behavior` property:

| Name | Definition |
| --- | --- |
| `transition-discrete` | `transition-behavior: allow-discrete` |
| `transition-normal` | `transition-behavior: normal` |


# Test plan

Not a lot too test here, but verified in the browser that these
properties generate correct CSS:
<img width="301" alt="image"
src="https://github.com/user-attachments/assets/db314750-e129-47d6-b605-d3b367ae81a4">
<img width="253" alt="image"
src="https://github.com/user-attachments/assets/24da5a6e-0b6a-48aa-a042-5ec19773bc6b">

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-20 05:39:16 -05:00
Jordan Pittman
a83b02b341
Fix negative rotate utilities (#15044)
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.
2024-11-19 15:27:47 -05:00
Jordan Pittman
b73c746e6e
Implement compat for <alpha-value> from v3 (#15033)
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.
2024-11-19 10:01:45 -05:00
Philipp Spiess
ab9e2b716b
Support complex addUtilities() configs (#15029)
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>
2024-11-19 15:52:06 +01:00
Robin Malfait
93f9c99027
Improve robustness when upgrading (#15038)
This PR improves the robustness when running the upgrade script.

Right now when you run it and if you run into issues, it could be that
an error with stack trace is printed in the terminal. This PR improves
most of the cases where this happens to ensure the output is easier to
parse as a human.

# Test plan:

Used SourceGraph to find some popular open source repositories that use
Tailwind and tried to run the upgrade tool on those repositories. If a
repository fails to upgrade, then that's a good candidate for this PR to
showcase the improved error messages.

github.com/docker/docs

| Before | After |
| --- | --- |
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/ae28c1c1-8472-45a2-89f7-ed74a703e216">
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/6bf4ec79-ddfc-47c4-8ba0-051566cb0116">
|

github.com/parcel-bundler/parcel

| Before | After |
| --- | --- |
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/826e510f-df7a-4672-9895-8e13da1d03a8">
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/a75146f5-bfac-4c96-a02b-be00ef671f73">
|

github.com/vercel/next.js

| Before | After |
| --- | --- |
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/8d6c3744-f210-4164-b1ee-51950d44b349">
| <img width="1455" alt="image"
src="https://github.com/user-attachments/assets/b2739a9a-9629-411d-a506-3993a5867caf">
|
2024-11-19 14:29:51 +01:00
Robin Malfait
dd3441bf82
Add new in-* variant (#15025)
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>
2024-11-18 15:28:16 +00:00
Robin Malfait
3dc3bad781
Re-introduce automatic var injection shorthand (#15020)
This PR re-introduces the automatic var injection feature.

For some backstory, we used to support classes such as `bg-[--my-color]`
that resolved as-if you wrote `bg-[var(--my-color)]`.

The is issue is that some newer CSS properties accepts dashed-idents
(without the `var(…)`). This means that some properties accept
`view-timeline-name: --my-name;` (see:
https://developer.mozilla.org/en-US/docs/Web/CSS/view-timeline-name).

To make this a tiny bit worse, these properties _also_ accept
`var(--my-name-reference)` where the variable `--my-name-reference`
could reference a dashed-ident such as `--my-name`.

This makes the `bg-[--my-color]` ambiguous because we don't know if you
want `var(--my-color)` or `--my-color`.

With this PR, we bring back the automatic var injection feature as
syntactic sugar, but we use a different syntax to avoid the ambiguity.
Instead of `bg-[--my-color]`, you can now write `bg-(--my-color)` to get
the same effect as `bg-[var(--my-color)]`.

This also applies to modifiers, so `bg-red-500/[var(--my-opacity)]` can
be written as `bg-red-500/(--my-opacity)`. To go full circle, you can
rewrite `bg-[var(--my-color)]/[var(--my-opacity)]` as
`bg-(--my-color)/(--my-opacity)`.

---

This is implemented as syntactical sugar at the parsing stage and
handled when re-printing. Internally the system (and every plugin) still
see the proper `var(--my-color)` value.

Since this is also handled during printing of the candidate, codemods
don't need to be changed but they will provide the newly updated syntax.

E.g.: running this on the Catalyst codebase, you'll now see changes like
this:
<img width="542" alt="image"
src="https://github.com/user-attachments/assets/8f0e26f8-f4c9-4cdc-9f28-52307c38610e">

Whereas before we converted this to the much longer
`min-w-[var(--button-width)]`.

---

Additionally, this required some changes to the Oxide scanner to make
sure that `(` and `)` are valid characters for arbitrary-like values.

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-18 15:47:48 +01:00
Philipp Spiess
5a974cd318
Bring back max-w-screen-* utilities (#15013)
This PR brings back the `max-w-screen-*` utilities from v3 that read
from the `--breakpoint` namespace.

Since these utilities are only added back for compatibility reasons,
it's put into the compatibility layer.

Note that this does not do Intellisense recommendations for the
functional utility.

## Test Plan

Unit tests are upgraded including some from the compat test that extends
the `--breakpoint` namespace from `screen` keys. Also tested this in the
Vite playground.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-16 15:10:54 -05:00
Robin Malfait
3fb6902f08
Make flex a static utility (#15014)
This PR makes `flex` a static utility, which also means that it is
located near the other static `display` utilities.

This is possible because we changed how `parseCandidate` returns an
array of utilities instead of a single utility.

This makes the code more consistent and a bit easier to understand.

Bonus: turns out that `flex` was never suggested to intellisense, but
now it is!
2024-11-15 17:02:57 +00:00
Philipp Spiess
2a6cd94b38
Bring back named opacity support for color opacity modifiers (#15009)
This PR reverts https://github.com/tailwindlabs/tailwindcss/pull/14278
to bring back support for using named opacity values in color opacity
modifiers:

```css
@theme {
  --opacity-myOpacity: 50%;
}
```

```html
<div class="bg-red-500/myOpacity"></div>
```

We briefly discuss to restructure the code so that we avoid adding a
`theme` argument to the call sites but I do still prefer the current
approach for the following reasons: The way to avoid this is to a) put
something in either the `Theme` class scope, where it feels grossly out
of place, or b) put it into the shared closure in the utilities file
which is already very large and hard to reason. Furthermore, there's a
second call site in the compile function where we would need to
duplicate the namespace lookup.

Every caller of the current `asColor` value already has access to the
`Theme` so passing that as an argument seems like the least intrusive
way.

## Test Plan

Brought back the unit tests but I also tested it with the Vite
extension:

<img width="744" alt="Screenshot 2024-11-15 at 11 15 05"
src="https://github.com/user-attachments/assets/63923b80-767e-4104-b7eb-f71fc815b51e">

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-15 14:43:12 +00:00
Philipp Spiess
953ecd2d19
Prepare v4.0.0-alpha.34 (#15002) 2024-11-14 18:23:40 +01:00
Philipp Spiess
890f18de93
Add codemod and interop for legacy container component configu (#14999)
This PR adds support for handling v3 [`container` customizations
](https://tailwindcss.com/docs/container#customizing). This is done by
adding a custom utility to extend the core `container` utility. A
concrete example can be taken from the added integration test.

### Input

```ts
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./src/**/*.html'],
  theme: {
    container: {
      center: true,
      padding: {
        DEFAULT: '2rem',
        '2xl': '4rem',
      },
      screens: {
        md: '48rem', // Matches a default --breakpoint
        xl: '1280px',
        '2xl': '1536px',
      },
    },
  },
}
```

### Output

```css
@import "tailwindcss";

@utility container {
  margin-inline: auto;
  padding-inline: 2rem;

  @media (width >= theme(--breakpoint-sm)) {
    max-width: none;
  }

  @media (width >= 48rem) {
    max-width: 48rem;
  }

  @media (width >= 1280px) {
    max-width: 1280px;
  }

  @media (width >= 1536px) {
    max-width: 1536px;
    padding-inline: 4rem;
  }
}
````


## Test Plan

This PR adds extensive tests to the compat layer as part of unit tests.
Additionally it does at a test to the codemod setup that shows that the
right `@utility` code is generated. Furthermore I compared the
implementation against v3 on both the compat layer and the custom
`@utility`:


https://github.com/user-attachments/assets/44d6cbfb-4861-4225-9593-602b719f628f
2024-11-14 12:19:21 -05:00
Robin Malfait
8538ad859c
Ensure @config is injected in common ancestor sheet (#14989)
This PR fixes an issue where an `@config` was injected in a strange
location if you have multiple CSS files with Tailwind directives.

Let's say you have this setup:
```css
/* ./src/index.css */
@import "./tailwind-setup.css";

/* ./src/tailwind-setup.css */
@import "./base.css";
@import "./components.css";
@import "./utilities.css";

/* ./src/base.css */
@tailwind base;

/* ./src/components.css */
@tailwind components;

/* ./src/utilities.css */
@tailwind utilities;
```

In this case, `base.css`, `components.css`, and `utilities.css` are all
considered Tailwind roots because they contain Tailwind directives or
imports.

Since there are multiple roots, the nearest common ancestor should
become the tailwind root (where `@config` is injected). In this case,
the nearest common ancestor is `tailwind-setup.css` (not `index.css`
because that's further away).

Before this change, we find the common ancestor between `base.css` and
`components.css` which would be `index.css` instead of
`tailwind-setup.css`.

In a next iteration, we compare `index.css` with `utilities.css` and
find that there is no common ancestor (because the `index.css` file has
no parents). This resulted in the `@config` being injected in
`index.css` and in `utilities.css`.

Continuing with the rest of the migrations, we migrate the `index.css`'s
`@config` away, but we didn't migrate the `@config` from
`utilities.css`.

With this PR, we don't even have the `@config` in the `utilities.css`
file anymore.

Test plan
---

1. Added an integration test with a non-migrateable config file to
ensure that the `@config` is injected in the correct file.
2. Added an integration test with a migrateable config file to ensure
that the CSS config is injected in the correct file. h/t @philipp-spiess
3. Ran the upgrade on the https://commit.tailwindui.com project and
ensured that
1. The `@config` does not exist in the `utilities.css` file (this was
the first bug we solved)
  2. The `@config` is replaced in the `tailwind.css` file correctly.

<img width="592" alt="image"
src="https://github.com/user-attachments/assets/02e3f6ea-a85d-46c2-ac93-09f34ac4a4b8">

<img width="573" alt="image"
src="https://github.com/user-attachments/assets/e372eb5f-5732-4052-ab39-096ba7970ff6">
2024-11-14 11:48:31 +01:00
Philipp Spiess
dd85aadc2c
Reintroduce container component as a utility (#14993)
Closes #13129

We're adding back the v3 `container` component, this time as a utility.
The idea is that we support the default `container` behavior but we will
not have an API to configure this similar to what v3 offered. Instead,
the recommended approach is to configure it by creating a custom utility
like so:

```css
@import "tailwindcss";

@utility container {
  margin-left: auto;
  margin-right: auto;
  padding-left: 2rem;
  padding-right: 2rem;
}
```

We do have an idea of how to migrate existing JS configuration files to
the new `@utility` as part of the interop layer and the codemod. This is
going to be a follow-up PR though.

## Test Plan

We added a unit test but we've also played around with it in the Vite
playground. Yep, looks like a `container`:


https://github.com/user-attachments/assets/ea7a5a4c-4cde-4ef5-9062-03e16239eb85

---------

Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
2024-11-13 13:39:20 -05:00