Commit Graph
100 Commits
Author SHA1 Message Date
Adam WathanandAdam 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
Adam WathanandAdam 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 WathanandAdam 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
Adam WathanandAdam 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 WathanandAdam 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
Adam WathanandAdam 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
Adam WathanandAdam 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
Adam WathanandAdam 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
Adam Wathan a56c3a3414 Update CHANGELOG.md 2024-11-21 09:06:36 -05:00
Adam Wathan 75deecadca Update CHANGELOG.md 2024-11-19 20:37:17 -05:00
Adam WathanandAdam Wathan 13f05e2711 Support specifying gradient interpolation method via modifier (#14984)
This PR adds support for specifying a color interpolation method for all
gradient utilities using a modifier:

```html
<div class="bg-linear-to-r/oklab">
```

Supported bare values are any valid color space keyword, as well as the
special keywords `shorter`, `longer`, `increasing`, and `decreasing`,
which are shortcuts for `in oklch {keyword} hue`.

Arbitrary values are also supported and are used as-is, so the `in`
keyword is not automatically included for you:

```html
<div class="bg-linear-to-r/[in_oklab]">
```

Modifiers are not supported when using arbitrary values for the actual
gradient, as it's expected that your arbitrary gradient value contain
all of the details you want in your gradient:


```html
<!-- Won't work -->
<div class="bg-linear-[to_right]/oklab">

<!-- Do this -->
<div class="bg-linear-[to_right_in_oklab]">
```

Resolves https://github.com/tailwindlabs/tailwindcss/issues/14955, but
it may still be wise to make `oklab` the default since I do sort of
agree with the poster there that most people probably expect a gradient
between two colors to sort of just "fade" between them rather than
interpolate between them around the color wheel.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-13 10:18:59 -05:00
Adam WathanandAdam Wathan 5ce575a83c Support opacity values in increments of 0.25 by default (#14980)
This PR updates all areas in the framework that accept opacity values
(`opacity-*`, `backdrop-opacity-*`, `bg-red-500/*`, etc.) to accept
fractional values in increments of 0.25 instead of just whole numbers.

We noticed we use values like `2.5` and `7.5` pretty regularly in our
templates and don't see why those should be treated as any more "weird"
than something like `opacity-63` which we already support, so baking
this in to core.

IntelliSense will still only suggest values in increments of `5` like it
did before.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-12 14:04:13 -05:00
Adam WathanandAdam Wathan 437579d3f0 Prepare v4.0.0-alpha.33 release (#14967)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 20:28:41 -05:00
Adam WathanandAdam Wathan 1ec1445ee6 Support spacing scale as line-height modifiers (#14966)
This PR fixes an issue where utilities like `text-sm/6` failed to
include a line-height because `--leading-6` is no longer an explicitly
defined theme value by default.

I don't really love seeing `calc(var(--spacing) * 9)` in the output here
admittedly and it's making me consider again if we should register this
variable as `inline` so we see the final computed value in the CSS, but
if we do that it's something we should change in a separate PR.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 16:49:34 -05:00
Adam Wathan d2c27492cf Revert "Update lightningcss-win32-x64-msvc 1.26.0 → 1.28.1 (minor)" (#14964)
Reverts tailwindlabs/tailwindcss#14956
2024-11-11 18:57:49 +00:00
Adam WathanandAdam Wathan 50d7355f7f Don't reset horizontal padding on date/time pseudo-elements (#14959)
Turns out all of these date/time pseudo elements have a bit of
horizontal padding on them that we don't want to throw away when fixing
the height issue, so this PR updates our reset to only remove vertical
padding.

Here's a demo showing the difference, test in Safari or Chrome to see
the difference in horizontal spacing:

https://play.tailwindcss.com/Opwa7pkDFP?file=css

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 13:11:28 -05:00
Adam WathanandAdam Wathan 7da9272d0f Prepare v4.0.0-alpha.32 (#14954)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 11:05:22 -05:00
Adam WathanandAdam Wathan 3244da8981 Sort theme variables in a more intentional order (#14952)
This PR updates our default `theme.css` file and organizes the CSS
variables in a custom order that's optimized for looking nice in Chrome
dev tools.

You can only see ~50 variables "above the fold" in dev tools without
clicking "Show all", so I've opted for putting variables near the top
that have the highest "impact" on the design/brand of the site, and also
showcase some of the modern CSS features we are using in Tailwind CSS
v4.

Here's what it looks like:

<kbd><img width="957" alt="image"
src="https://github.com/user-attachments/assets/dade9244-6e22-4822-ac5c-ffa33e895f6e"></kbd>

I really want to show off the color palette because the swatches look
nice and because seeing `oklch` there feels like a nice signal for
Tailwind CSS v4 being very modern, but we have a lot of colors so you
can't really fit much else if you do this. I stuck font families at the
top since it's one of the few things that we can fit there that also
feels important to your site's brand but still has few enough values not
to push away the color palette.

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-11 10:08:49 -05:00
Adam WathanandAdam Wathan 4f76980651 Make leading-none a static utility (#14934)
This PR removes the `--leading-none` variable from the default theme in
favor of making `leading-none` a static utility, since it doesn't make
sense to change the value of this on a per-project basis. This is
consistent with how `none` values work for other utilities in the
framework.

Some folks in the past have wanted `leading-none` to be `line-height: 0`
but technically "leading" is the space between lines, and `line-height:
1` removes all extra space between lines so it feels correct to me
(although it means all of the numeric utilities like `leading-6` are not
technically correct but I try hard not to think about that too much).

If someone wants `line-height: 0` they can use `leading-0` in v4 since
the `leading-*` utilities inherit the spacing scale now.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-09 09:40:57 -05:00
Adam WathanandAdam Wathan e1c74ca935 Deprecate shadow-inner utility (#14933)
This PR deprecates the `shadow-inner` value in favor of
`inset-shadow-sm` which does the same thing but is composable with other
outer shadows.

It's still included in the default theme but is registered as `inline
reference` and doesn't add any CSS variables to the output.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-09 09:32:04 -05:00
Adam WathanandAdam Wathan 1dbd99d373 Reintroduce deprecated theme values (#14932)
This PR reintroduces the `blur`, `shadow`, `drop-shadow`, and `rounded`
utilities that were removed in #14849, just to preserve backward
compatibility as much as possible.

These values are still considered deprecated, and we register them as
`inline reference` with the theme to ensure they don't produce any CSS
variables in output:

```css
/* Deprecated */
@theme default inline reference {
  --blur: 8px;
  --shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1);
  --drop-shadow: 0 1px 2px rgb(0 0 0 / 0.1), 0 1px 1px rgb(0 0 0 / 0.06);
  --radius: 0.25rem;
}
```

These values won't be included in the documentation, and in the future
we'll add an option to explicitly register things as `deprecated` so
that they don't appear as completions in IntelliSense either.

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-09 09:21:40 -05:00
Adam WathanandAdam Wathan 5da6968996 Normalize date/time input styles (#14931)
This PR adds some additional styles to Preflight to normalize a bunch of
inconsistencies in date/time inputs across browsers.

The main motivation for this is to remove these insane classes we have
to add in Catalyst:

```html
<input type="date" class="[&::-webkit-datetime-edit-fields-wrapper]:p-0 [&::-webkit-date-and-time-value]:min-h-[1.5em]
[&::-webkit-datetime-edit]:inline-flex [&::-webkit-datetime-edit]:p-0 [&::-webkit-datetime-edit-year-field]:p-0
[&::-webkit-datetime-edit-month-field]:p-0 [&::-webkit-datetime-edit-day-field]:p-0
[&::-webkit-datetime-edit-hour-field]:p-0 [&::-webkit-datetime-edit-minute-field]:p-0
[&::-webkit-datetime-edit-second-field]:p-0 [&::-webkit-datetime-edit-millisecond-field]:p-0
[&::-webkit-datetime-edit-meridiem-field]:p-0"/>
```

With these normalizations, changing things like padding, display type,
etc. gives consistent results (at least as consistent as is actually
possible) across all browsers.

---

**Make text alignment work on iOS Safari**

<kbd><img width="418" alt="iOS Safari text alignment"
src="https://github.com/user-attachments/assets/0ff792b2-1f3a-40c6-9185-6bd076c8715d"></kbd>

---

**Don't shrink date inputs on iOS Safari when there is no selected
value**

<kbd><img width="409" alt="ioS Safari no input"
src="https://github.com/user-attachments/assets/a8e69af7-3f0c-4d1d-b7a0-10355a5d3907"></kbd>

---

**Fix padding in macOS Safari**

<kbd><img width="717" alt="MacOS Safari"
src="https://github.com/user-attachments/assets/5ea19b66-2dec-46e2-a386-d61bd5b8517a"></kbd>

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-08 16:43:56 -05:00
Adam WathanandAdam Wathan 56288a318a Remove input borders by default (#14929)
This PR reverts a change we made for v4 that added borders to inputs by
default. It feels like we have to go further than this for this to
actually be useful to anyone, and since there were no borders in v3 it's
also a breaking change.

If we wanted to make form elements look more "normal" out of the box I
think we need to do something more like this:

https://play.tailwindcss.com/icCwFLVp4z?file=css

But it's a huge rabbit hole and there are so many stupid details to get
right that it feels like an insurmountable task, and if we can't go all
the way with it it's better to just maximize compatibility with v3.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-08 15:29:41 -05:00
Adam WathanandAdam Wathan bcddc81f66 Replace outline-none with outline-hidden, add new outline-none (#14926)
This PR renames the existing `outline-none` utility to `outline-hidden`,
and adds a new simpler `outline-none` utility that just sets
`outline-style: none`.

The existing `outline-none` utility doesn't actually set `outline:
none`, and instead creates a 2px invisible outline:

```css
.outline-none {
  outline: 2px solid transparent;
  outline-offset: 2px;
}
```

We implemented it this way because people often use `outline: none` to
hide focus rings and replace them with custom shadow-based focus rings,
without realizing that that approach leads to no visible focus ring in
forced colors mode because box shadows aren't rendered in forced colors
mode.

While this is sort of helpful and clever, it can be a pain when you
really do need `outline: none`, and I think it feels surprising in
hindsight to hijack the name of an existing CSS property value and make
it mean something else.

The name `outline-hidden` feels better because it's a new keyword that
CSS doesn't use for outlines, and implies that perhaps there's a bit
more going on than just setting `outline-style: none`.

This PR includes a codemod to convert any existing use of `outline-none`
to `outline-hidden`, and we will be sure to explain what
`outline-hidden` does for you in the v4 documentation.

Manually tested this in the Vite playground to make sure it behaves as
expected 👍

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-08 20:03:12 +01:00
Adam WathanandAdam Wathan 192109bd01 Don't give input elements a transparent background by default (#14913)
Early in v4 development we decided to give all form controls a
transparent background, but in v3 we only did this for button elements.

This PR reverts that decision to make things consistent with v3, as
we've noticed this is something that tends to break for people when
upgrading from v3 to v4.

The default background color of form elements is the [`Field` system
color](https://developer.mozilla.org/en-US/docs/Web/CSS/system-color#field)
which automatically adapts to light and dark modes if you don't touch
it, so it feels reasonable to keep this as the default. Changing it just
makes upgrading harder and doesn't really make anything easier for
anyone else.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-08 10:19:29 -05:00
Adam WathanandAdam Wathan 54ddbb1273 Ensure spacing utilities with no value (e.g. px) don't generate CSS (#14911)
This PR fixes an issue where utilities like `px` would read the
`--spacing` variable and use its value as the utility value, similar to
how `shadow` reads `--shadow` by default. That doesn't make sense for
these utilities since `--spacing` is reserved as a special multiplier
variable.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-08 09:49:42 -05:00
28e46badf7 Rename --font-size-* variables to --text-* (#14909)
This PR updates all of the `--font-size-*` variables to `--text-*`
instead to closer match the utility names.

```diff
  @theme {
-   --font-size-xs: 0.75rem;
-   --font-size-xs--line-height: 1rem;
-   --font-size-sm: 0.875rem;
-   --font-size-sm--line-height: 1.25rem;
-   --font-size-base: 1rem;
-   --font-size-base--line-height: 1.5rem;
-   --font-size-lg: 1.125rem;
-   --font-size-lg--line-height: 1.75rem;
-   --font-size-xl: 1.25rem;
-   --font-size-xl--line-height: 1.75rem;

    /* ... */
  
+   --text-xs: 0.75rem;
+   --text-xs--line-height: 1rem;
+   --text-sm: 0.875rem;
+   --text-sm--line-height: 1.25rem;
+   --text-base: 1rem;
+   --text-base--line-height: 1.5rem;
+   --text-lg: 1.125rem;
+   --text-lg--line-height: 1.75rem;
+   --text-xl: 1.25rem;
+   --text-xl--line-height: 1.75rem;

    /* ... */
  }
```

This is part of a bigger set of changes where we're renaming other theme
variables as well with the same goals, since many existing theme
variables like `--shadow-*` and `--radius-*` are already not using the
explicit CSS property name.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-11-07 14:08:06 -05:00
Adam WathanandAdam Wathan a4f8a36413 Don't unset keys like --font-weight-* when unsetting --font-* (#14906)
This PR fixes an issue where unsetting `--font-*` would unset
`--font-weight-*` and `--font-size-*`.

```css
@theme {
  --font-weight-bold: bold;
  --font-size-sm: 14px;
  --font-sans: sans-serif;
  --font-serif: serif;
}
@theme {
  --font-*: initial;
  --font-body: Inter;
}
```

Up until now this was sort of intended/desired behavior but with recent
changes there are now more overlapping theme keys (`--inset-*` and
`--inset-shadow-*` as well for example), and we don't want to make it
impossible to unset _just_ the default `font-family` values.

This PR also simplifies how we were handling making sure that the
`inset-*` utility ignored `--inset-shadow-*` variables since it's all
really the same problem.

This does mean we need to maintain a list of known theme keys so we know
when there is a conflict between two keys, which is kind of unfortunate
because up until now this was a totally dynamic thing. End users can
still add whatever custom stuff they want under `@theme` but we don't
really know about those namespaces since we're maintaining a static list
so we can't resolve conflicts there. I'm confident there are ways we
could solve this if it actually becomes a problem, so content to push
forward without solving it right now and just deal with it if/when it
actually arises, because it just might not.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-07 10:43:49 -05:00
Adam WathanandAdam Wathan 26638af3ef Rename --width-* namespace to --container-* (#14898)
This PR renames all of the `--width-*` variables to `--container-*` to
better communicate the purpose of these tokens as layout container
sizes. These are the values that were historically stored under
`maxWidth` in the v3 and earlier eras, and were also re-used by the
container queries plugin.

The name `--container-*` feels like a better match alongside the
`--breakpoint-*` namespace and since these both serve that same sort of
purpose it makes sense to me that the name should be optimized for
feeling "right" in that context.

I like that this also sort of advertises Tailwind's support for
container queries directly in the CSS variables themselves, and helps
people understand what these are really intended to be used for.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-06 20:50:30 -05:00
Adam WathanandAdam Wathan 32cf4af2a4 Rename --transition-timing-function-* variables to --ease-* (#14886)
This PR renames the `--transition-timing-function-*` theme variables to
`--ease-*` to more closely match the utility names and be a bit more
terse in general.

```diff
  @theme {
-   --transition-timing-function-in: cubic-bezier(0.4, 0, 1, 1);
-   --transition-timing-function-out: cubic-bezier(0, 0, 0.2, 1);
-   --transition-timing-function-in-out: cubic-bezier(0.4, 0, 0.2, 1);

+   --ease-in: cubic-bezier(0.4, 0, 1, 1);
+   --ease-out: cubic-bezier(0, 0, 0.2, 1);
+   --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  }
```

This is part of a bigger set of changes where we're renaming other theme
variables as well with the same goals, since many existing theme
variables like `--shadow-*` and `--radius-*` are already not using the
explicit CSS property name.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-06 10:51:34 -05:00
Adam WathanandAdam Wathan 2aea6e9d37 Rename --font-family-* variables to --font-* (#14885)
This PR renames the `--font-family-*` theme variables to `--font-*` to
more closely match the utility names and be a bit more terse in general.

```diff
  @theme {
-   --font-family-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
-   --font-family-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
-   --font-family-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
    
+   --font-sans: ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji';
+   --font-serif: ui-serif, Georgia, Cambria, 'Times New Roman', Times, serif;
+   --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace;
  }
```

This is part of a bigger set of changes where we're renaming other theme
variables as well with the same goals, since many existing theme
variables like `--shadow-*` and `--radius-*` are already not using the
explicit CSS property name.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-06 10:33:44 -05:00
Adam WathanandAdam Wathan 8bd3c85420 Derive all font-weight values from theme (#14883)
This PR removes all of the static `font-weight` utilities that were
previously hard-coded into the framework in favor of deriving those
utilities from the `--font-weight-*` theme values instead.

Biggest motivation for this is giving people a way to explicitly disable
font-weight utilities they don't want to use in their project, which
previously wasn't possible.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-05 16:06:47 -05:00
Adam WathanandAdam Wathan 7175605c61 Remove fallbacks from theme var(...) calls (#14881)
This PR changes how we render `var(...)` calls for theme values,
removing the fallback values we were previously including.

```diff
  .text-white {
-   color: var(--color-white, #fff);
+   color: var(--color-white);
  }
```

We previously included the fallbacks only so you could see the value in
dev tools but this feels like a bad reason to bloat the CSS. I'd rather
just convince the Chrome team to surface this stuff better in dev tools
in the first place.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-05 15:44:21 -05:00
Adam WathanandAdam Wathan c50de9384a Replace default explicit spacing scale with multiplier system (#14857)
This PR replaces the default spacing scale (`--spacing-*`) with a
generative system based on a default spacing _unit_.

Instead of the default theme containing values like `--spacing-4`,
`--spacing-6`, `--spacing-8`, etc., instead we just define a single
`--spacing` value:

```css
@theme {
  --spacing: 0.25rem;
}
```

Utilities like `px-4` are derived from this unit by multiplying it by
the value in the utility (4 in this case):

```css
.px-4 {
  padding-inline: calc(var(--spacing) * 4);
}
```

The biggest consequence of this change is that every value is available
now, rather than just the explicitly configured values.

This means utilities like `px-42` will work now, whereas prior to this
PR only `px-40` and `px-44` were valid utilities. I personally found it
very difficult to know which values actually existed at the higher end
of the scale without IntelliSense, and in practice even when working
with a skilled designer like [Steve](https://x.com/steveschoger) who
helped design Tailwind's default spacing scale, I'd very often need to
break out of it to implement a design, and trying to round to a value
that was in the scale made the design worse, not better.

This PR allows you to use any whole number, as well as decimal numbers
that are multiples of `0.25` to ensure classes like `px-1.5` continue to
work. While this means you can now technically do things like
`pt-97.25`, I think the presence of the fractional value will be enough
of a signal to developers that they are doing something a little
unusual, and they can use their judgment as to whether they are making
the right decision or not.

I'll update this PR with a lot more detail when I have a chance, as
there are a few other things to explain like:

- Unifying all of the values for
width/min-width/max-width/height/min-height/max-height utilities
- Deriving numeric line-height values from the spacing multiplier
instead of a separate line-height scale
- Using `--spacing: initial` to disable the multiplier
- How you can still use an explicit spacing scale and ignore this change
- How we plan to use IntelliSense to surface a more curated set of
spacing values even if smaller increments work when you type them
explicitly

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-05 15:22:50 -05:00
Adam WathanandAdam Wathan b63f493768 Make ease-linear a static utility (#14880)
This PR removes `--transition-timing-function-linear` from the default
theme in favor of a static `ease-linear` utility. Doesn't make sense for
this to be a design token since `linear` can only mean `linear`.

This is consistent with how we handle basically every other similar case
in the framework.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-05 12:34:44 -05:00
Adam WathanandAdam Wathan ca4e4aebd8 Adjust shadow, radius, and blur scales to ensure all utilities have a value suffix (#14849)
This PR reworks the default `--shadow-*` and `--inset-shadow-*` scales
to remove the bare `shadow` and `inset-shadow` utilities, and ensure
every shadow has an explicit size as part of the utility name.

Here's a complete list of changes:

| v3                | v4 Alpha          | Proposed           |
| ----------------- | ----------------- | ------------------ |
| _N/A_             | `shadow-xs`       | `shadow-2xs`       |
| `shadow-sm`       | `shadow-sm`       | `shadow-xs`        |
| `shadow`          | `shadow`          | `shadow-sm`        |
| `shadow-md`       | `shadow-md`       | `shadow-md`        |
| `shadow-lg`       | `shadow-lg`       | `shadow-lg`        |
| `shadow-xl`       | `shadow-xl`       | `shadow-xl`        |
| _N/A_ | `inset-shadow-xs` | `inset-shadow-2xs` |
| _N/A_ | `inset-shadow-sm` | `inset-shadow-xs`  |
| `shadow-inner`    | `inset-shadow`    | `inset-shadow-sm`     |

The motivation for this change is just to make the scale more
predictable — it's never been intuitive to me that `shadow` sits in
between `shadow-sm` and `shadow-md`.

This PR doesn't remove the ability to create classes like `shadow` and
`inset-shadow` by adding bare `--shadow` and `--inset-shadow` theme
variables, but does remove them from the default theme.

## Impact

We'll include a codemod for this in our upgrade tool to automate this
change for people upgrading from v3 to v4, but this is still sort of an
annoying breaking change admittedly and will make lots of educational
resources, example components, and LLM tools out of date for v4 😕 At the
same time I don't want to feel like we can never correct regrettable
legacy decisions just to preserve backward compatibility.

We made a similar change like this when we went from the v0.x color
palette to the v1.x color palette changing names like `bg-red` to
`bg-red-500` and that proved to definitely be the right decision long
term, so want to rip the band-aid off here too if we can.

Planning to make the same change for `rounded`, `drop-shadow`, and
`blur` as well — maybe in separate PRs but maybe just all in this one as
well since I don't think we want to do one and not all.

_Update_: I've also made the same changes to the `--radius-*`,
`--drop-shadow-*`, and `--blur-*` scales now, effectively removed the
`rounded`, `drop-shadow`, and `blur` classes by default, and changing
the meaning `rounded-sm`, `drop-shadow-sm`, and `blur-sm`.

We'll put together a codemod to handle this stuff in a separate PR.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-04 14:04:03 -05:00
Adam WathanandAdam Wathan cf77420b0c Ensure --inset-ring=* and --inset-shadow-* variables are ignored by inset-* utilities (#14855)
This PR fixes a issue where utilities like `inset-x-*`, `left-*`,
`top-*`, etc. mistakenly pull values from the `--inset-ring-*` and
`--inset-shadow-*` theme namespaces.

For example, the class `left-shadow-sm` currently generates this CSS:

```css
.left-shadow-sm {
  left: var(
    --inset-shadow-sm,
    inset 0 1px 1px rgb(0 0 0 / 0.05)
  );
}
```

This happens because the `--inset-ring-*` and `--inset-shadow-*`
namespaces collide with the `--inset-*` namespace.

We were already handling this manually for just the `inset-*` utilities
but didn't realize we needed to handle it for every related utility, so
this PR fixes that.

This also fixes an issue where IntelliSense would suggest classes like
`inset-x-shadow-sm` when they shouldn't actually exist.

To do this we've created this new concept of `ignoredThemeKeys` in the
relevant APIs to make sure these are filtered out at the source.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-11-01 13:48:42 -04:00
Adam WathanandAdam Wathan 63b321b7ea Remove --drop-shadow-none from default theme (#14847)
This PR removes `--drop-shadow-none` from the default theme which
shouldn't ever have been there since we handle all `*-none` utilities as
static/permanent utilities in the framework now.

I've added `drop-shadow-none` as an explicit static utility, and also
slightly improved test coverage for `getClassList` around drop shadows
while touching this part of the code.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-31 14:24:18 -04:00
Adam WathanandAdam Wathan 289c25f8e9 Use inline and block for x/y utilities (#14805)
This PR updates all of our x/y named utilities (like `px-*`, `my-*`,
`inset-y-*`, `scroll-px-*`, etc.) to use logical properties like
`padding-inline` instead of separate `padding-left` and `padding-right`
properties.

We held off on this originally for a while because `inline` doesn't
really mean _horizontal_ like the "x" in `px-*` implies, but I think in
practice this change is fine — I'm comfortable with "x" meaning "in the
inline direction" and "y" meaning "in the block direction" in Tailwind.

This is technically a breaking change if anyone was depending on the
fact that `px-*` for instance was always explicitly setting
`padding-left` and `padding-right` even when building something in a
vertical writing mode, but I kinda doubt there's a single real project
on the internet that will actually be affected, so not too worried about
it.

If someone _really_ wants to set `padding-left` and `padding-right` they
can always use `pl-4 pr-4` instead of `px-4`.

Nice thing about this change is it produces quite a bit less CSS.

To test this change, I re-generated all of the snapshots and made sure
none of the generated utilities changed position or anything in the
output (initially they did before I updated `property-order.ts` to add
some missing properties).

I also created a little demo locally in the Vite playground to test
things manually and make sure I didn't make any obvious typos or
anything that could slip through the snapshots:

<img width="1223" alt="image"
src="https://github.com/user-attachments/assets/0e9854ba-2b5b-4c8c-87b6-6eb7b7da84f2">

<details>
<summary>Show code for playground demo</summary>

```jsx
import React from 'react'

export function App() {
  return (
    <div className="p-12 gap-10 grid grid-cols-2 items-start">
      <div className="grid grid-cols-1 gap-10 justify-start">
        <div className="space-y-6">
          <p className="font-semibold mb-6">Border Width</p>
          <div className="border-x w-48 h-12 flex items-center justify-center">border-x</div>
          <div className="border-y w-48 h-12 flex items-center justify-center">border-y</div>
        </div>
        <div className="space-y-6">
          <p className="font-semibold mb-6">Border Color</p>
          <div className="border-2 border-x-red-500 w-48 h-12 flex items-center justify-center">
            border-x-red-500
          </div>
          <div className="border-2 border-y-red-500 w-48 h-12 flex items-center justify-center">
            border-y-red-500
          </div>
        </div>
        <div className="space-y-6">
          <p className="font-semibold mb-6">Padding</p>
          <div>
            <div className="px-8 bg-yellow-300 inline-flex items-center justify-center">px-8</div>
          </div>
          <div>
            <div className="py-8 bg-yellow-300 inline-flex items-center justify-center">py-8</div>
          </div>
        </div>
      </div>
      <div className="grid grid-cols-1 gap-10 justify-start">
        <div className="space-y-6">
          <p className="font-semibold mb-6">Margin</p>
          <div>
            <div className="bg-red-400 inline-flex">
              <div className="mx-8 bg-yellow-300 inline-flex items-center justify-center">mx-8</div>
            </div>
          </div>
          <div>
            <div className="bg-red-400 inline-flex">
              <div className="my-8 bg-yellow-300 inline-flex items-center justify-center">my-8</div>
            </div>
          </div>
        </div>
        <div className="space-y-6">
          <p className="font-semibold mb-6">Inset</p>
          <div className="relative bg-red-400 w-48 h-48">
            <div className="inset-x-8 absolute bg-yellow-300 inline-flex items-center justify-center">
              inset-x-8
            </div>
          </div>
          <div className="relative bg-red-400 w-48 h-48">
            <div className="inset-y-8 absolute bg-yellow-300 inline-flex items-center justify-center">
              inset-y-8
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
```

</details>

I didn't manually test the scroll padding or scroll margin utilities
because they are more annoying to set up, but I probably should.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-28 13:08:39 -04:00
Adam WathanandAdam Wathan 1eab49d0b1 Sort text wrapping utilities with typography utilities (#14787)
This PR implements some changes to the way we sort typography utilities,
inspired by #14715.

Prior to this PR, utilities like `text-balance`, `break-words`, and
`text-center` were sorted very early, even before things like border
utilities:

```html
<div class="text-balance break-words border-2 border-blue-500 text-center indent-5 text-2xl font-medium capitalize leading-6 tracking-tight text-red-500 underline"></div>
```

This PR changes the sort order to co-locate these with other typography
utilities which feels a lot more natural:

```html
<div class="border-2 border-blue-500 text-center indent-5 text-2xl leading-6 font-medium tracking-tight text-balance break-words text-red-500 capitalize underline"></div>
```

I've also made some small adjustments to how other typography properties
are sorted based on pairing with @reinink and just deciding what felt
the most intuitive to us and matched the order we'd likely type things
in manually.

To test this change I temporarily added a new test to `sort.test.ts` to
make sure the classes were sorted in the expected order:

```js
  [
    // Input
    'text-red-500 text-center capitalize text-2xl break-words text-balance underline font-medium tracking-tight leading-6 indent-5',

    // Expected
    'text-center indent-5 text-2xl leading-6 font-medium tracking-tight text-balance break-words text-red-500 capitalize underline',
  ],
```

Didn't keep the test around because there's no real logic to test here
(it just matches the order in the `property-order.ts` file) and we don't
have any other tests like this.

I've also made some minor unrelated changes here like deleting legacy
properties from `property-order.ts` that are never used, and fixing a
typo where we wrote `work-break` instead of `word-break`.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-24 16:10:20 -04:00
39cfcfa427 Register migrateImport to ensure it actually runs (#14769)
This PR makes sure the `migrateImport` codemod is properly registered so
that it runs as part of the upgrade process.

## Test plan

This PR adds a new `v3` playground with an `upgrade` script that you can
use to run the upgrade from the local package. When you add a
non-prefixed `@import` to the v3 example, the paths are now properly
updated with no errors logged:


https://github.com/user-attachments/assets/85949bbb-756b-4ee2-8ac0-234fe1b2ca39

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
2024-10-24 11:00:25 -04:00
Adam WathanandAdam Wathan d643d79f4b Ensure individual logical property utilities are sorted later than left/right pair utilities (#14777)
Resolves #14772.

This PR fixes an issue where utilities like `ps-2` were sorted earlier
in the generated CSS than `px-3`, causing `ps-2` to not override `px-3`
as expected.

This happened because `px-3` uses `padding-left` and `padding-right`,
and `ps-2` uses `padding-inline-start`, and in `property-order.ts` we
sort those properties as follows:

```js
  ...
  'padding',
  'padding-inline',
  'padding-block',
  'padding-inline-start',
  'padding-inline-end',
  'padding-top',
  'padding-right',
  'padding-bottom',
  'padding-left',
  ...
```

Since `padding-left` and `padding-right` both appear later than
`padding-inline-start`, the `px-3` utility is sorted later in the CSS
since all of its properties are later in the sort order than all of
properties in `ps-2`.

To fix this, I'm using our internal `--tw-sort` property to tell
Tailwind to sort the `px-3` utility as if it used `padding-inline` to
ensure that it's sorted earlier in the CSS.

This PR applies this same fix for the `padding` utilities,
`scroll-margin` utilities, and `scroll-padding` utilities. No changes
have been made to the `margin` utilities because we were already
handling this correctly there.

Here you can see that `pl-2` overrides `px-6` as you'd expect:

<img width="1041" alt="image"
src="https://github.com/user-attachments/assets/fb330536-2131-4de8-a584-62edf380148f">

…and now with the change in this PR, `ps-2` also overrides `px-6` as
you'd expect:

<img width="1043" alt="image"
src="https://github.com/user-attachments/assets/c6799416-9c80-4fd5-bce4-ea1e4da53968">

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-24 10:58:41 -04:00
Adam WathanandAdam Wathan 1c5bb39d60 Use 0 instead of none in OKLCH values (#14741)
This PR updates all of our OKCLH colors to use `0` instead of `none` due
to weird behavior in Chrome where using `color-mix` with colors using
`none` produces unexpected results:

<img width="1110" alt="image"
src="https://github.com/user-attachments/assets/2272e494-500b-4f75-b5c1-d41c714f0339">

Both `none` and `0` behave as expected in Safari and Firefox so
suspecting this is a bug in Chrome rather than spec'd behavior.

Fixes #14740

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-21 15:54:27 -04:00
Adam WathanandAdam Wathan b701ed6916 Prepare v4.0.0-alpha.28 release (#14709)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-17 17:03:28 -04:00
Adam WathanandAdam Wathan edb066e0aa Interpolate gradients using OKLCH by default (#14708)
This PR updates all of our gradient utilities to interpolate using OKLCH
by default instead of sRGB. This results in a smoother transition
between colors that preserves saturation throughout the gradient, rather
than hitting the dreaded dull gray zone in between your color stops.

Here are a few examples comparing sRGB (top) to OKLCH (bottom):

<img width="736" alt="image"
src="https://github.com/user-attachments/assets/57a158b6-a3a2-4eda-813e-1b596c7d4b3a">

We only apply a default interpolation mode when _not_ using arbitrary
values with the gradient utility.

Simplified but clear:

```css
.bg-linear-to-r {
  background-image: linear-gradient(to right in oklch, var(--gradient-color-stops));
}

.bg-linear-[to_right] {
  background-image: linear-gradient(to right, var(--gradient-color-stops));
}

.bg-linear-[to_right_in_hsl] {
  background-image: linear-gradient(to right in hsl, var(--gradient-color-stops));
}
```

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-17 16:16:14 -04:00
Adam WathanandAdam Wathan 72c30d422a Support linear gradient angles as bare values (#14707)
This PR adds support for linear gradient angles as bare values, like
this:

```
bg-linear-45 => linear-gradient(45deg, …)
```

We already support this for [conic
gradients](https://github.com/tailwindlabs/tailwindcss/pull/14467), so
this makes these utilities more consistent.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-17 14:29:32 -04:00
Adam WathanandAdam Wathan feeb9f1b77 Remove invalid gradient fallbacks (#14705)
Prior to this PR we were providing fallback values for certain CSS
variables in our gradient utilities that just weren't necessary and
didn't do anything.

For example `bg-linear-to-r` was generating this:

```css
.bg-linear-to-r {
  --tw-gradient-position: to right;
  background-image: linear-gradient(
    var(--tw-gradient-stops, to right)
  );
}
```

…but `background-image: linear-gradient(to right)` is not valid CSS and
is thrown out by the browser.

This PR removes these fallback values entirely since there is nothing
sensible to fall back to anyways — you need to combine these utilities
with the `from-*`/`to-*` utilities or provide the complete gradient as
an arbitrary value for things to make sense.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-17 13:48:58 -04:00
Adam WathanandAdam Wathan 2d45f5aa9a Add first draft of new wide-gamut color palette (#14693)
This PR updates all of the colors in our default theme to use OKLCH
instead of RGB and increases the overall chroma to take advantage of the
wider color gamut.

Just a first draft based on @danhollick's initial work — expecting these
will be further refined before a stable release as we continue to test
them.

<img width="628" alt="image"
src="https://github.com/user-attachments/assets/2de1bfca-fddd-47f9-b609-39f26abdee41">

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-16 15:24:53 -04:00
Adam Wathan 7c7acace5c Tweak changelog entries (#14649) 2024-10-11 10:38:46 -04:00
Adam Wathan 5a2938dbfc Update CHANGELOG.md 2024-10-11 09:50:53 -04:00
Adam Wathan 0f37845a3d Update CHANGELOG.md 2024-10-03 13:22:21 -04:00
Adam Wathan 51afa7d658 Update CHANGELOG.md 2024-10-03 12:52:18 -04:00
dae178ef6a Add color-scheme utilities (#14567)
Replaces #11271 — the merge conflicts are killing me and it's way easier
to just do it again (added you as a co-author though @lukewarlow so
you're still credited!)

This PR adds the following new utilities for the `color-scheme`
property:

| Class               | CSS                        |
| ------------------- | -------------------------- |
| `scheme-normal`     | `color-scheme: normal`     |
| `scheme-dark`       | `color-scheme: dark`       |
| `scheme-light`      | `color-scheme: light`      |
| `scheme-light-dark` | `color-scheme: light dark` |
| `scheme-only-dark`  | `color-scheme: dark only`  |
| `scheme-only-light` | `color-scheme: light only` |

Went with `scheme-*` for the utilities because there are currently no
other CSS properties with the word `scheme` in them and
`scheme-light-dark` is going to be a common value which is three words
already even with the shortened property name.

I considered setting `color-scheme: light dark` by default as part of
Preflight for this PR but decided against it, at least for this PR. I
think that could still be a useful default but we should think about it
a bit more because if you're building a light-mode-only site it'll force
you to do some extra work.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
2024-10-02 06:07:55 -04:00
Adam WathanandAdam Wathan 3693a71a10 Test @import "tailwindcss" prefix(tw) explicitly + move prefix tests (#14566)
I noticed our prefix tests were missing an explicit test for `@import
"tailwindcss" prefix(tw)` so this PR tweaks an existing test to test
that case.

Also noticed that `prefix.test.ts` was in the `compat` folder even
though this is a v4 feature, so moved it out to the root.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-10-01 13:20:18 -04:00
abde4c9694 Only apply hover on devices that support hover (#14500)
This PR updates the `hover` variant to only apply when `@media (hover:
hover)` matches.

```diff
  .hover\:bg-black {
    &:hover {
+     @media (hover: hover) {
        background: black;
+     }
    }
  }
```

This is technically a breaking change because you may have built your
site in a way where some interactions depend on hover (like opening a
dropdown menu), and were relying on the fact that tapping on mobile
triggers hover.

To bring back the old hover behavior, users can override the `hover`
variant in their CSS file back to the simpler implementation:

```css
@import "tailwindcss";
@variant hover (&:hover);
```

I've opted to go with just `@media (hover: hover)` for this because it
seems like the best trade-off between the available options. Using
`(any-hover: hover)` would mean users would get sticky hover states when
tapping on an iPad if they have a mouse or trackpad connected, which
feels wrong to me because in those cases touch is still likely the
primary method of interaction.

Sites built with this feature in mind will be treating hover styles as
progressive enhancement, so it seems better to me that using an iPad
with a mouse would not have hover styles, vs. having sticky hover styles
in the same situation.

Of course users can always override this with whatever they want, so
making this the default isn't locking anyone in to a particular choice.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-09-24 11:43:57 -04:00
Adam WathanandAdam Wathan 6d43a8be99 Preserve explicit transition duration and timing function when overriding transition property (#14490)
This PR changes the behavior of the `transition-{property}` utilities to
respect any explicit timing function or duration set by the user using
the `ease-*` and `duration-*` utilities.

Say you have this HTML:

```html
<div class="transition-colors duration-500 ease-out lg:transition-all">
```

Currently, the `transition-duration` and `transition-timing-functions`
will be reset to their default values at the `lg` breakpoint even though
you've provided explicit values for them.

After this PR is merged, those values will be preserved at the `lg`
breakpoint.

This PR also adds `duration-initial` and `ease-initial` utilities to
"unset" explicit duration/timing-function values so that the defaults
from classes like `transition-all` will kick in, without having to
specify their explicit values.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-23 10:43:28 -04:00
Adam WathanandAdam Wathan 222a93c0a3 Include gradient color properties in color transitions (#14489)
This PR adds our custom gradient color properties (`--tw-gradient-from`,
`--tw-gradient-via`, and `--tw-gradient-to`) to the list of color
properties we transition in the `transition` and `transition-colors`
utilities.

As part of this I noticed that we had duplicate `@property` declarations
for these custom properties, so I've removed the duplicates.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-23 09:07:54 -04:00
Adam WathanandAdam Wathan 0daaaebc5e Include --default-transition-* variables in transition-* utility output (#14482)
Fixes #14479.

Back in March we made a change to the `transition-*` utilities that
inlined the values of the `--default-transition-*` variables to fix a
bug where things would break if those variables didn't exist in your
CSS. At the time though we weren't outputting CSS variables as part of
the values of any utilities, for example `bg-red-500` didn't actually
reference the `--color-red-500` variable.

We later changed that but missed this situation, so these variables were
still inlined even though nothing else was.

This PR fixes that and makes things more consistent, so these variables
will be used as expected unless using the `@theme inline` option, like
with everything else.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-20 12:40:44 -04:00
Adam WathanandAdam Wathan eb3bb4422a Add shadow-initial and inset-shadow-initial utilities (#14468)
This PR complements #14458 by adding new `shadow-initial` and
`inset-shadow-initial` utilities that make it possible to "undo" a
custom shadow color and revert to the default shadow color for the
current shadow size.

For example, in this example the shadow will be red on hover even though
the default color for the `shadow` utility is `rgb(0 0 0 / 5%)`:

```html
<div class="shadow-sm shadow-red-500 hover:shadow">
  <!-- … -->
</div>
```

This is usually what you want, but if you actually want `hover:shadow`
to apply its default color, you need to know what the color is and add
it yourself:

```html
<div class="shadow-sm shadow-red-500 hover:shadow hover:shadow-black/5">
  <!-- … -->
</div>
```

Using `shadow-initial`, you can achieve the same thing without having to
know what the original color was:

```html
<div class="shadow-sm shadow-red-500 hover:shadow hover:shadow-initial">
  <!-- … -->
</div>
```

The `inset-shadow-initial` utility does the same thing for the
`inset-shadow-*` utilities.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-20 10:36:22 -04:00
Adam WathanandAdam Wathan bf115bf1bd Add radial and conic gradient utilities (#14467)
This PR adds new `bg-radial-*` and `bg-conic-*` utilities for radial and
conic gradients. It also adds support for "arbitrary gradients", where
gradient utilities like `bg-linear-*`, `bg-radial-*`, and `bg-conic-*`
can now accept a complete gradient definition as their arbitrary value.

## Radial gradients

Radial gradients are created with the `bg-radial` utility, or the
`bg-radial-[…]` utility, combined with the existing `from-*`, `via-*`,
and `to-*` utilities.

The simple `bg-radial` utility just creates a radial gradient with no
position information, which defaults to `center`:

```
radial-gradient({from}, {via}, {to});
```

If you use the arbitrary value format, whatever you provide as the
arbitrary value is inserted into the first position:

```
radial-gradient({arbitrary value}, {from}, {via}, {to});
```

So a utility like `bg-radial-[at_top_left]` would produce this:

```
radial-gradient(at top left, {from}, {via}, {to});
```

This makes it possible to use some of the `radial-gradient(…)` features
that this PR doesn't add first class support for, like using values like
`circle at center` or providing a specific interpolation color space
like `in hsl longer hue`. We may add explicit APIs for these in the
future, but I'm proposing this PR first since those changes would be
purely additive and none of the decisions here would create any conflict
with those APIs.

## Conic gradients

Conic gradients are created with the `bg-conic`,
`bg-conic-{bareNumber}`, and `bg-conic-[…]` utilities, combined with the
existing `from-*`, `via-*`, and `to-*` utilities.

The `bg-conic` utility creates a conic gradient with no angle, which
defaults to `0deg`:

```
conic-gradient({from}, {via}, {to});
```

The `bg-conic-{bareNumber}` utilities create conic gradients using the
bare number as the angle:

```
conic-gradient(from {bareNumber}deg, {from}, {via}, {to});
```

The `bg-conic-[…]` arbitrary value utilities insert whatever you provide
as the arbitrary value into the first position verbatim:

```
conic-gradient({arbitraryValue}, {from}, {via}, {to});
```

So a utility like `bg-conic-[from_45deg_in_hsl]` would produce this:

```
conic-gradient(from 45deg in hsl, {from}, {via}, {to});
```

Note that the `from` keyword needs to be provided by the user when using
arbitrary values, but not when using bare values.

This makes it possible to use some of the `conic-gradient(…)` features
that this PR doesn't add first class support for, like using values like
`at 0 0` or providing a specific interpolation color space like `in hsl
longer hue`. We may add explicit APIs for these in the future, but I'm
proposing this PR first since those changes would be purely additive and
none of the decisions here would create any conflict with those APIs.

## Arbitrary gradients

Prior to this PR, utilities like `bg-linear-[…]` could only accept
positional information as their arbitrary value, like
`bg-linear-[to_top_right]`. All of the color stops could only be
provided using the `from-*`, `via-*`, and `to-*` utilities.

If you wanted to provide the complete gradient in one class, you needed
to use `bg-[…]` and write out the gradient function yourself:


```html
<div class="bg-[linear-gradient(to_right,var(--color-red-500),var(--color-yellow-400))]">
```

This PR refactors some things internally to make it possible to provide
the entire gradient as the arbitrary value to each background gradient
utility, like this:

```html
<div class="bg-linear-[to_right,var(--color-red-500),var(--color-yellow-400)]">
```

This is nice if you're doing something very custom and you want to be
able to look at the whole value together, while still avoiding some of
the boilerplate you'd have if you had to write out the entire gradient
function yourself.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-20 10:34:54 -04:00
Adam WathanandAdam Wathan 8d00534823 Preserve shadow color when overriding shadow size (#14458)
This PR changes how shadow color and shadow size utilities interact when
used with variants.

Take this HTML:

```html
<div class="shadow-lg shadow-red-500 hover:shadow-xl">
  <!-- … -->
</div>
```

Currently this shadow would be red by default, but revert to the default
semi-transparent black color on hover.

This PR changes this behavior such that the shadow remains red on hover,
and only the shadow size changes.

We deliberately didn't do this originally because making things behave
this way makes it very difficult to get the default shadow color back
once you've changed it. The default color for `shadow-xl` for instance
is `rgb(0 0 0 / 0.1)`, and the only way to get that color back after
changing it is to know that value and explicitly bring it back:

```html
<div class="shadow-lg shadow-red-500 hover:shadow-xl hover:shadow-black/10">
  <!-- … -->
</div>
```

To make things more difficult, the default shadow color is not the same
across shadow sizes. For `shadow-sm` it's `black/5`, and for
`shadow-2xl` it's `black/25`.

In practice though you basically never need to bring back the default
shadow color, so I'm reconsidering this trade-off in v4, and think I
prefer this new behavior where the color is preserved but you have to
bring back the default color if you actually need it.

A simple workaround if you don't know the color is to reset the
`--tw-shadow-color` variable like this:

```html
<div class="shadow-lg shadow-red-500 hover:shadow-xl hover:[--tw-shadow-color:initial]">
  <!-- … -->
</div>
```

This relies on semi-private internals though, so perhaps we can
introduce a utility for this, like `shadow-default` or `shadow-initial`
that just unsets the shadow color.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-19 09:43:48 -04:00
a51b63a05d Don't override explicit leading-*, tracking-*, or font-{weight} utilities with font-size utility defaults (#14403)
This PR improves how the `text-{size}` utilities interact with the
`leading-*`, `tracking-*`, and `font-{weight}` utilities, ensuring that
if the user explicitly uses any of those utilities that those values are
not squashed by any defaults baked into the `text-{size}` utilities.

Prior to this PR, if you wrote something like this:

```html
<div class="text-lg leading-none md:text-2xl">
```

…the `leading-none` class would be overridden by the default line-height
value baked into the `text-2xl` utility at the `md` breakpoint. This has
been a point of confusion and frustration for people [in the
past](https://github.com/tailwindlabs/tailwindcss/issues/6504) who are
annoyed they have to keep repeating their custom `leading-*` value like
this:

```html
<div class="text-lg leading-none md:text-2xl md:leading-none lg:text-4xl lg:leading-none">
```

This PR lets you write this HTML instead but get the same behavior as
above:

```html
<div class="text-lg leading-none md:text-2xl lg:text-4xl">
```

It's important to note that this change _only_ applies to line-height
values set explicitly with a `leading-*` utility, and does not apply to
the line-height modifier.

In this example, the line-height set by `text-sm/6` does _not_ override
the default line-height included in the `md:text-lg` utility:

```html
<div class="text-sm/6 md:text-lg">
```

That means these two code snippets behave differently:

```html
<div class="text-sm/6 md:text-lg">…</div>
<div class="text-sm leading-6 md:text-lg">…</div>
```

In the top one, the line-height `md:text-lg` overrides the line-height
set by `text-sm/6`, but in the bottom one, the explicit `leading-6`
utility takes precedence.

This PR applies the same improvements to `tracking-*` and
`font-{weight}` as well, since all font size utilities can also
optionally specify default `letter-spacing` and `font-weight` values.

We achieve this using new semi-private CSS variables like we do for
things like transforms, shadows, etc., which are set by the `leading-*`,
`tracking-*`, and `font-{weight}` utilities respectively. The
`text-{size}` utilities always use these values first if they are
defined, and the default values become fallbacks for those variables if
they aren't present.

We use `@property` to make sure these variables are reset to `initial`
on a per element basis so that they are never inherited, like with every
other variable we define.

This PR does slightly increase the amount of CSS generated, because now
utilities like `leading-5` look like this:

```diff
  .leading-5 {
+   --tw-leading: 1.25rem;
    line-height: 1.25rem;
  }
```

…and utilites like `text-sm` include a `var(…)` lookup that they didn't
include before:

```diff
  .text-sm {
    font-size: 0.875rem;
-   line-height: var(--font-size-sm--line-height, 1.25rem);
+   line-height: var(--tw-leading, var(--font-size-sm--line-height, 1.25rem));
  }
```

If this extra CSS doesn't feel worth it for the small improvement in
behavior, we may consider just closing this PR and keeping things as
they are.

This PR is also a breaking change for anyone who was depending on the
old behavior, and expected the line-height baked into the `md:text-lg`
class to take precedence over the explicit `leading-6` class:

```html
<div class="text-sm leading-6 md:text-lg">…</div>
```

Personally I am comfortable with this because of the fact that you can
still get the old behavior by preferring a line-height modifier:

```html
<div class="text-sm/6 md:text-lg">…</div>
```

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
2024-09-18 09:20:04 -04:00
c817453560 Explicitly ignore --inset-shadow and --inset-ring variables in inset handler (#14447)
Resolves #14440.

This PR fixes an issue where registering a custom `inset-shadow-*`
utility value in your theme like this:

```css
@theme {
  --inset-shadow-potato: inset 0px 2px 6px #7a4724;
}
```

…mistakenly generates both an `inset-shadow-*` and `inset-*` utility
with that value:

```css
.inset-shadow-potato {
  inset: inset 0px 2px 6px #7a4724;
}

.inset-shadow-potato {
  box-shadow: inset 0px 2px 6px #7a4724;
}
```

This replaces #14445 which turns out to not be the ideal solution.

Now we just explicitly ignore variables like `--inset-shadow-*` and
`--inset-ring-*` in the `inset` handler. Kind of a gross patch but I can
live with it because the whole existence of the `--inset-*` key is kind
of a backwards compatibility thing anyways.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
2024-09-18 08:59:39 -04:00
8b0fff6edd Extract more backwards compatibility logic to compatibility layer (#14365)
I noticed a lot more backwards compatibility concerns had started
leaking into core, especially around the `theme` function, so did a bit
of work to try and pull that stuff out and into the compatibility layer.

Now the core version of `theme` only handles CSS variables (like
`--color-red-500`) and has no knowledge of the dot notation or how to
upgrade it. Instead, we unconditionally override that function in the
compatibility layer with a light version that _does_ know how to do the
dot notation upgrade, and override that again with the very heavy/slow
version that handles JS config objects only if plugins/JS configs are
actually used.

I've also renamed `registerPlugins` to `applyCompatibilityHooks` because
the name was definitely a bit out of date given how much work it's doing
now, and now call it unconditionally from core, leaving that function to
do any conditional optimizations itself internally.

Next steps I think would be to split up `plugin-api.ts` a bit and maybe
make `applyCompatibilityHooks` its own file, and move both of those
files into the `compat` folder so everything is truly isolated there.

My goal with this stuff is that if/when we ever decide to drop backwards
compatibility with these features in the future (maybe v5), that all we
have to do is delete the one line of code that calls
`applyCompatibilityHooks` in `index.ts`, and delete the `compat` folder
and we're done. I could be convinced that this isn't a worthwhile goal
if we feel it's making the codebase needlessly complex, so open to that
discussion as well.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-09-11 16:17:02 +02:00
Adam WathanandAdam Wathan 7b59aac274 Properly resolve theme('someKey.DEFAULT') when only --some-key-* keys exist (#14354)
This PR fixes an issue where theme function calls like
`theme('transitionTimingFunction.DEFAULT')` would incorrectly resolve to
an object when the set of defined CSS theme values looked like this:

```css
@theme {
  --transition-timing-function-in: ease-in;
  --transition-timing-function-out: ease-out;
  --transition-timing-function-in-out: ease-out;
}
```

We were mistakenly retrieving the entire
`--transition-timing-function-*` namespace in this case and returning an
object, even though the user is explicitly asking for a single value by
including `.DEFAULT` in their call.

This ensures it resolves to null instead. Fixes an issue I ran into on
this live stream earlier today:

https://x.com/adamwathan/status/1831740214051799281

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-06 09:00:28 -04:00
Adam Wathan 7725a5fbb6 Update CHANGELOG.md 2024-09-04 15:46:39 -04:00
Adam Wathan 2c89645d26 Update CHANGELOG.md 2024-09-04 15:45:25 -04:00
Adam WathanandAdam Wathan 530774b186 Ensure --default-font-* and --default-mono-font-* variables respect theme customizations in JS config files (#14344)
This PR fixes an issue where variables like `--default-font-family`
wouldn't behave as expected when customizing `fontFamily.sans` or
`fontFamily.mono` in a JS config.

Because theme values added by JS config files are added as `reference`,
customizing `fontFamily.sans` means the `--font-family-sans` variable no
longer exists in the generated CSS.

The `--default-font-family` variable is set to `var(--font-family-sans)`
by default, so because that variable doesn't exist,
`--default-font-family` is effectively undefined and the browser default
font stack is used. This is unexpected because historically customizing
`fontFamily.sans` has updated your default font for your entire project.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-04 15:30:21 -04:00
Adam WathanandAdam Wathan 262e99e5a9 Support arrays in JS config values (#14343)
This PR fixes a small bug where theme values could not be defined as
arrays in JS config files, for example:

```js
export default {
  theme: {
    fontFamily: {
      sans: ['Inter', 'system-ui', 'sans-serif'],
    },
  },
}
```

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-04 15:03:46 -04:00
Adam WathanandAdam Wathan d6a67beb76 Add default option to @theme to support overriding default theme values from plugins/JS config files (#14327)
This PR adds a new `default` option to `@theme` to make it possible for
plugins/JS config files to override default theme values, and also
ensures that the final set of CSS variables we output takes into account
any theme values added by plugins/JS config files.

---

Previously, if you were using the default theme but also had a JS config
file that overrode any of those defaults like this:

```js
// ./tailwind.config.js
export default {
  theme: {
    extend: {
      colors: {
        red: {
          '500': 'tomato',
        },
      }
    }
  }
}
```

…then utilities like `text-red-500` would correctly use `color: tomato`,
but the `--color-red-500` CSS variable would still be set to the default
value:

```css
:root {
  --color-red-500: #ef4444;
}
```

This feels like a straight-up bug — if `#ef4444` is not part of your
design system because you've overridden it, it shouldn't show up in your
set of CSS variables anywhere.

So this PR fixes this issue by making sure we don't print the final set
of CSS variables until all of your plugins and config files have had a
chance to update the theme.

---

The second issue is that we realized people have different expectations
about how plugin/config theme values should interact with Tailwind's
_default_ theme vs. explicitly user-configured theme values.

Take this setup for instance:

```css
@import "tailwindcss";
@config "./tailwind.config.js";
```

If `tailwind.config.js` overrides `red-500` to be `tomato`, you'd expect
`text-red-500` to actually be `tomato`, not the default `#ef4444` color.

But in this setup:

```css
@import "tailwindcss";
@config "./tailwind.config.js";
@theme {
  --color-red-500: #f00;
}
```

…you'd expect `text-red-500` to be `#f00`. This is despite the fact that
currently in Tailwind there is no difference here — they are both just
`@theme` blocks, one just happens to be coming from an imported file
(`@import "tailwindcss"`).

So to resolve this ambiguity, I've added a `default` option to `@theme`
for explicitly registering theme values as "defaults" that are safe to
override with plugin/JS config theme values:

```css
@import "tailwindcss";
@config "./tailwind.config.js";
@theme default {
  --color-red-500: #f00;
}
```

Now `text-red-500` would be `tomato` here as per the config file.

This API is not something users are generally going to interact with —
they will almost never want to use `default` explicitly. But in this PR
I've updated the default theme we ship with to include `default` so that
it interacts in a more intuitive way with plugins and JS config files.

---

Finally, this PR makes sure all theme values registered by
plugins/configs are registered with `isReference: true` to make sure
they do not end up in the final CSS at all.

This is important to make sure that the super weird shit we used to do
in configs in v3 doesn't get translated into nonsense variables that
pollute your output (hello typography plugin I'm looking at you).

If we don't do this, you'll end up with CSS variables like this:

```css
:root {
  --typography-sm-css-blockquote-padding-inline-start: 1.25em;
}
```

Preventing theme values registered in plugins/configs from outputting
CSS values also serves the secondary purpose of nudging users to migrate
to the CSS config if they do want CSS variables for their theme values.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-04 11:49:50 -04:00
Adam WathanandAdam Wathan 6d0371afb1 Evaluate theme functions in plugins (#14326)
This PR fixes a bug where CSS `theme()` functions were not evaluated
when present in rules added by plugins, using either `@plugin` or
registering a plugin in a JS config file.

For example, prior to this PR the `theme()` functions in this plugin
would make it into the final CSS without being evaluated:

```js
// ./my-plugin.js
export default plugin(({ addBase }) => {
  addBase({
    '.my-rule': {
      background: 'theme(colors.primary)',
      color: 'theme(colors.secondary)',
    },
  })
})
```

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-04 11:49:01 -04:00
Adam WathanandAdam Wathan dcfaaac8f6 Prepare v4.0.0-alpha.21 (#14313)
<!--

👋 Hey, thanks for your interest in contributing to Tailwind!

**Please ask first before starting work on any significant new
features.**

It's never a fun experience to have your pull request declined after
investing a lot of time and effort into a new feature. To avoid this
from happening, we request that contributors create an issue to first
discuss any significant new features. This includes things like adding
new utilities, creating new at-rules, or adding new component examples
to the documentation.


https://github.com/tailwindcss/tailwindcss/blob/master/.github/CONTRIBUTING.md

-->

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-09-02 15:43:28 -04:00
45fb21e753 Add support for the theme() function in the plugin API (#14207)
This PR adds support for the [`theme()`
function](https://tailwindcss.com/docs/plugins#dynamic-utilities) from
the v3 plugin API, used for configuring which values functional
utilities support:

```js
plugin(function({ matchUtilities, theme }) {
  matchUtilities(
    {
      tab: (value) => ({
        tabSize: value
      }),
    },
    { values: theme('tabSize') }
  )
})
```

Things this handles:

- "Upgrading" theme keys to their v4 names, so if you do
`theme('colors')` that will correctly retrieve all the colors from the
`--color-*` namespace with the new CSS variable based configuration
- Polyfilling dependent keys, so `theme('backgroundColor')` will still
pull everything in `--color-*` even though there is no values in the
`backgroundColor` namespace in v4 by default
- Polyfilling theme values that are now handled by "bare values"
internally, so even though there is no `flexShrink` theme values in v4,
`theme('flexShrink')` will still configure your plugin to properly
support any value that the built-in `shrink-*` utilities support

Things that aren't handled:

- Theme values that have been replaced by static utilities can't be
retrieved yet, so for example `theme('cursor')` returns nothing right
now because there are no values for the `cursor-*` utilities in the
theme anymore, they are all just baked in to the framework.

This will be handled in a future PR.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-20 11:05:08 -04:00
3df38a7458 Don't wrap relative selectors in arbitrary variants with :is(…) (#14203)
Prior to this PR, we weren't accounting for the fact that `:has(…)`
supports [relative
selectors](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_selectors/Selector_structure#relative_selector),
which are sort of like partial selectors that can start with a
combinator like `>`, `+`, or `~`.

Before, a class like `has-[>img]:flex` would generate this:

```css
.has-\[\>img\]\:flex:has(*:is(> img)) {
  display: flex;
}
```

This was incorrect because `*:is(> img)` isn't even valid CSS at all, so
the rule would do nothing.

After this change, we generate this instead:

```css
.has-\[\>img\]\:flex:has(> img) {
  display: flex;
}
```

This PR also ensures that relative selectors are recognized as invalid
in places where they are not supported, so classes like
`group-[>img]:flex` for example will produce nothing now instead of
invalid CSS.

This is mostly a simple change but it did involve storing some
additional information in the variant AST.

Fixes #14202.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-16 13:42:04 -04:00
Adam Wathan d55852a17c Update CHANGELOG.md 2024-08-08 10:05:38 -04:00
Adam Wathan 8a01fabb6d Update CHANGELOG.md 2024-08-08 10:05:15 -04:00
e000caa0bd Add support for inline option when defining @theme values (#14095)
This PR adds support for a new `inline` option when defining a `@theme`
block that tells Tailwind to use raw theme values for utilities instead
of referencing the corresponding generated CSS variable.

```css
/* Input */
@theme inline {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
:root {
  --color-red-500: #ef4444;
}

.text-red-500 {
  color: #ef4444;
}
```

This can be composed with the existing `reference` option in case you
want to define a `@theme` block as both `reference` (so the variables
aren't generated) and `inline`:

```css
/* Input */
@theme inline reference {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
.text-red-500 {
  color: #ef4444;
}
```

Since you can have multiple `@theme` blocks, you can even define some
values normally and some as inline based on how you're using them. For
example you might want to use `inline` for defining literal tokens like
`--color-red-500`, but include the variable for tokens that you want to
be able to theme like `--color-primary`:

```css
/* Input */
@theme inline {
  --color-red-500: #ef4444;
  /* ... */
}

@theme {
  --color-primary: var(--color-red-500);
}


/* Example output */
:root {
  --color-red-500: #ef4444;
  --color-primary: var(--color-red-500);
}

.text-red-500 {
  color: #ef4444;
}

.text-primary {
  color: var(--color-primary, var(--color-red-500));
}
```

## Breaking changes

Prior to this PR, you could `@import` a stylesheet that contained
`@theme` blocks as reference by adding the `reference` keyword to your
import:

```css
@import "./my-theme.css" reference;
```

Now that `reference` isn't the only possible option when declaring your
`@theme`, this syntax has changed to a new `theme(…)` function that
accepts `reference` and `inline` as potential space-separated values:

```css
@import "./my-theme.css";
@import "./my-theme.css" theme(reference);
@import "./my-theme.css" theme(inline);
@import "./my-theme.css" theme(reference inline);
```

If you are using the `@import … reference` option with an earlier alpha
release, you'll need to update your code to `@import … theme(reference)`
once this PR lands in a release.

## Motivation

This PR is designed to solve an issue pointed out in #14091.

Prior to this PR, generated utilities would always reference variables
directly, with the raw value as a fallback:

```css
/* Input */
@theme {
  --color-red-500: #ef4444;
  /* ... */
}


/* Example output */
:root {
  --color-red-500: #ef4444;
}

.text-red-500 {
  color: var(--color-red-500, #ef4444);
}
```

But this can create issues with variables resolving to an unexpected
value when a theme value is referencing another variable defined on
`:root`.

For example, say you have a CSS file like this:

```css
:root, .light {
  --text-fg: #000; 
}

.dark {
  --text-fg: #fff;
}

@theme {
  --color-fg: var(--text-fg);
}
```

Without `@theme inline`, we'd generate this output if you used the
`text-fg` utility:

```css
:root, .light {
  --text-fg: #000; 
}

.dark {
  --text-fg: #fff;
}

:root {
  --color-fg: var(--text-fg);
}

.text-fg {
  color: var(--color-fg, var(--text-fg));
}
```

Now if you wrote this HTML, you're probably expecting your text to be
the dark mode color:

```html
<div class="dark">
  <h1 class="text-fg">Hello world</h1>
</div>
```

But you'd actually get the light mode color because of this rule:

```css
:root {
  --color-fg: var(--text-fg);
}

.text-fg {
  color: var(--color-fg, var(--text-fg));
}
```

The browser will try to resolve the `--color-fg` variable, which is
defined on `:root`. When it tries to resolve the value, _it uses the
value of `var(--text-fg)` as it would resolve at `:root`_, not what it
would resolve to based on the element that has the `text-fg` class.

So `var(--color-fg)` resolves to `#000` because `var(--text-fg)`
resolved to `#000` at the point in the tree where the browser resolved
the value of `var(--color-fg)`.

By using `@theme inline`, the `.text-fg` class looks like this:

```css
.text-fg {
  color: var(--text-fg);
}
```

With this definition, the browser doesn't try to resolve `--color-fg` at
all and instead resolves `--text-fg` directly which correctly resolves
to `#fff` as expected.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-08-02 09:37:30 -04:00
Adam WathanandAdam Wathan 50a6a37dc9 Prepare for v4.0.0-alpha.18 release (#14057)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-25 10:19:13 -04:00
Adam WathanandAdam Wathan 8eca436b3c Reduce specificity of * variant (#14056)
This PR reduces the specificity of the * variant so that classes
directly on the child elements take precedence over the styles applied
by the parent.

Previously a utility like `*:flex` would generate this CSS:

```css
.\*\:flex > * {
  display: flex;
}
```

This selector has a specificity of `0,1,0`, which is the same as the
specificity for a bare utility class like `flex`, `block`, or `grid`.

Because variants always appear later in the CSS file than bare
utilities, this means that given this HTML, the `grid` class on the
child element would have no effect:

```html
<div class="*:flex">
  <div>...</div>
  <div class="grid">...</div>
  <div>...</div>
</div>
```

After this PR, the `*:flex` utility generates this CSS instead:

```css
:where(.\*\:flex > *) {
  display: flex;
}
```

This selector has a specificity of `0,0,0`, so even though it appears
later in the CSS, a bare utility with a specificity of `0,1,0` will
still take precedence.

This is something we wanted to do when we first introduced the `*`
variant in the v3 series, but couldn't because having such a low
specificity meant that styles in Preflight would take precedence over
utilities like `*:flex`, which is not would anyone would want.

We can make this change for v4 because now all of Preflight is wrapped
in a dedicated `@layer`, and rules from later layers always take
precedence over rules from earlier layers even if the rule in the later
layer has a lower specificity.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-25 10:09:47 -04:00
54474086c8 Add support for basic addVariant plugins with new @plugin directive (#13982)
* Add basic `addVariant` plugin support

* Return early

* Load plugins right away instead later

* Use correct type for variant name

* Preliminary support for addVariant plugins in PostCSS plugin

* Add test for compounding plugin variants

* Add basic `loadPlugin` support to Vite plugin

* Add basic `loadPlugin` support to CLI

* add `io.ts` for integrations

* use shared `loadPlugin` from `tailwindcss/io`

* add `tailwindcss-test-utils` to `@tailwindcss/cli` and `@tailwindcss/vite`

* only add `tailwindcss-test-utils` to `tailwindcss` as a dev dependency

Because `src/io.ts` is requiring the plugin.

* move `tailwindcss-test-utils` to `@tailwindcss/postcss `

This is the spot where we actually need it.

* use newer pnpm version

* Duplicate loadPlugin implementation instead of exporting io file

* Remove another io reference

* update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-07-11 09:47:26 -04:00
Adam WathanandAdam Wathan 407de01e8d Use initial for @property fallbacks instead of (#13949)
* Use `initial` for `@property` fallbacks instead of ` `

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-07-04 11:20:05 -04:00
Adam WathanandAdam Wathan 62de02a379 Support combining arbitrary shadows without a color with shadow color utilities (#13876)
* Support combining arbitrary shadows without a color with shadow color utilities

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-06-21 17:36:59 -04:00
Adam WathanandAdam Wathan 4f7a79168b Include variable in output for bare utilities like rounded (#13836)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-06-14 09:25:05 -04:00
Adam WathanandAdam Wathan 0060508c6e Declare character code constants per file (#13500)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-04-11 12:44:44 +02:00
Adam WathanandAdam Wathan 818692fe17 Don't accommodate hidden elements in space/divide (#13459)
* Don't accommodate hidden elements in space/divide

* Update tests

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-04-09 12:59:08 -04:00
Adam WathanandAdam Wathan cc6094e84f Don't read variables for shadow sizes (#13449)
* Don't read variables for shadow sizes

* Add UI test

* Handle key suffix in get function instead of ThemeKey

* Remove duplicate theme keys

* Format test in a less insane way

* Revert playground changes

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-04-04 18:01:37 -04:00
Adam WathanandAdam Wathan 4aefd26f44 Don't reset ::first-letter in Preflight (#13408)
* Don't reset ::first-letter in Preflight

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-30 08:06:53 -04:00
59038c5734 Include :popover-open in open variant (#13331)
* Include :popover-open in open variant

Co-Authored-By: Luke Warlow <lwarlow@igalia.com>

* Update changelog

* Remove accidental package.json change

* Revert playground changes

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Luke Warlow <lwarlow@igalia.com>
2024-03-22 16:00:07 -04:00
de79455b0e Add variant for @starting-style (#13329)
* Add variant for @starting-style

Co-Authored-By: Han Yeong-woo <han@yeongwoo.dev>

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Han Yeong-woo <han@yeongwoo.dev>
2024-03-22 15:38:06 -04:00
Adam WathanandAdam Wathan 0f69d4fe6e [v4] Make 3D rotations composable (#13319)
* Reorganize to co-locate rotate/skew/transform

* Make 3D rotations composable

* Uppercase axis in rotate functions

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-22 13:31:57 -04:00
b5df5e9202 Use variables with fallbacks for utility classes (#13177)
* Use variables with fallbacks for utility classes

* Update playwright test

* rename `resolveBare` to `resolveValue`

* make private methods really private

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-03-21 18:25:43 +01:00
89a0b86e73 Remove bare value handling for perspective utilities (#13288)
* Remove bare value handling for perspective utilities

* move `perspective-123` example

This is now moved to the spot where we ensure that nothing is generated
at all. This prevents us from accidentally updating a snapshot and
missing a potential bug.

* update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
2024-03-20 15:25:24 +01:00
Adam WathanandAdam Wathan 91fca13981 Don't rely on existence of --default-transition-* variables in transition utilities (#13219)
* Don't rely on existence of --default-transition-* variables in transition utilities

* Update changelog

* Add test with no default transition values defined

* Inline value for --default-transition-timing-function

This is more consistent with how things worked in v3 and ensures things will still work if the user suppresses the output of all CSS variables.

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-13 12:14:05 -04:00
Adam WathanandAdam Wathan 4e1f98141a Support @theme reference without @import (#13222)
* Support `@theme reference` without `@import`

* Fix test

* Update tests

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-12 14:07:01 -04:00
Adam WathanandAdam Wathan 65f6f7c1ca Prepare alpha.8 release (#13203)
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-11 15:10:21 -04:00
Adam WathanandAdam Wathan 78d1c50f1c Reset borders, padding, and margin universally (#13189)
* Reset borders, padding, and margin universally

Noticed iframes have a default border we weren't resetting, feels safest to just remove borders across the board and reintroduce them for form controls.

We were also resetting padding on an element by element basis but I can't think of any elements we are actually trying to avoid resetting padding on, so just reset it everywhere.

This also removes the left margin on file buttons that separates the button from the meta data about the currently selected file but I think this is fine, let the user decide how much space to put there intentionally like we do with other things.

* Include ::first-letter

Supports margin/padding/border (but not box-sizing) so should be in reset list.

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-11 14:17:19 -04:00
Adam WathanandAdam Wathan d863de7abf Prevent content-none from being overridden when conditionally styling ::before/::after (#13187)
* Prevent content-none from being overridden when conditionally styling before/after

* Update changelog

* Fix changelog entry

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-11 14:09:50 -04:00
Adam WathanandAdam Wathan 8309b47266 Remove static radius values from theme (#13186)
* Remove static radius values from theme

* Update snapshots

* Update changelog

* Use static utilities + a big loop

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-11 14:02:18 -04:00
5c5037d9b5 Ensure scale utilities support percentages (#13182)
* Ensure scale utilities support percentages

* Update changelog

* Fix changelog entry

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: wongjn <11310624+wongjn@users.noreply.github.com>
2024-03-11 13:14:10 -04:00
Adam WathanandAdam Wathan 277e2cdd4c Parse CSS files with CRLF line endings (#13162)
* Parse CSS files with CRLF line endings

* Update changelog

---------

Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
2024-03-08 21:28:58 +01:00