Upgrading `lightningcss` to fix invalid `list-style: none` conversion.
I've also reverted the change to preflight while at it, since it's no
longer necessary.
This PR makes sure that the `--theme(…)` CSS function can only be used
with the modern syntax. For backwards compatibility, the `theme(…)`
function must be used with the older dot notation.
This PR improves the codemod tool to simplify 2 things:
1. Whenever you have a `theme(…)` call, we try to change it to a
`var(…)`, but if that doesn't work for some reason, we will make sure to
at least convert it to the more modern `--theme(…)`.
2. When converting `theme(spacing.2)`, we used to convert it to
`calc(var(--spacing)*2)`, but now we will convert it to `--spacing(2)`
instead.
Closes#15438Closes#15560Closes#15561Closes#15562
This PR upgrades `lightningcss` to `1.29.0` and uses the [new feature
flag](304389600f)
to disable the light-dark function transpilation.
This PR fixes an issue where JavaScript plugins were still able to
contribute `@keyframes` when loaded inside an `@reference` import. This
was possible because we only gated the `addBase` API and not the
`addUtilities` one which also has a special branch to handle `@keyframe`
rules.
To make this work, we have to create a new instance of the plugin API
that has awareness of wether the plugin accessing it is inside reference
import mode.
## Test plan
Added a unit test that reproduces the issue observed via #15544
This PR fixes an issue where static utilities defined via `@utility`
wasn't possible if the name starts with `-`.
There are plenty of static utilities that start with `-`, but it wasn't
possible to register them via the `@utility` directive, only via the JS
API.
Example of a core utility that is now valid:
```css
@utility -inset-full {
inset: -100%;
}
```
This PR implements new CSS functions that you can use in your CSS (or
even in arbitrary value position).
For starters, we renamed the `theme(…)` function to `--theme(…)`. The
legacy `theme(…)` function is still available for backwards
compatibility reasons, but this allows us to be future proof since
`--foo(…)` is the syntax the CSS spec recommends. See:
https://drafts.csswg.org/css-mixins/
In addition, this PR implements a new `--spacing(…)` function, this
allows you to write:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: --spacing(4):
}
```
This is syntax sugar over:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: calc(var(--spacing) * 4);
}
```
If your `@theme` uses the `inline` keyword, we will also make sure to
inline the value:
```css
@import "tailwindcss";
@theme inline {
--spacing: 0.25rem;
}
.foo {
margin: --spacing(4):
}
```
Boils down to:
```css
@import "tailwindcss";
@theme {
--spacing: 0.25rem;
}
.foo {
margin: calc(0.25rem * 4); /* And will be optimised to just 1rem */
}
```
---
Another new function function we added is the `--alpha(…)` function that
requires a value, and a number / percentage value. This allows you to
apply an alpha value to any color, but with a much shorter syntax:
```css
@import "tailwindcss";
.foo {
color: --alpha(var(--color-red-500), 0.5);
}
```
This is syntax sugar over:
```css
@import "tailwindcss";
.foo {
color: color-mix(in oklab, var(--color-red-500) 50%, transparent);
}
```
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Co-authored-by: Jonathan Reinink <jonathan@reinink.ca>
This PR adds support for functional utilities constructed via CSS.
# Registering functional utilities in CSS
To register a functional utility in CSS, use the `@utility potato-*`
syntax, where the `-*` signals that this is a functional utility:
```css
@utility tab-* {
tab-size: --value(--tab-size-*);
}
```
## Resolving values
The special `--value(…)` function is used to resolve the utility value.
### Resolving against `@theme` values
To resolve the value against a set of theme keys, use
`--value(--theme-key-*)`:
```css
@theme {
--tab-size-1: 1;
--tab-size-2: 2;
--tab-size-4: 4;
--tab-size-github: 8;
}
@utility tab-* {
/* tab-1, tab-2, tab-4, tab-github */
tab-size: --value(--tab-size-*);
}
```
### Bare values
To resolve the value as a bare value, use `--value({type})`, where
`{type}` is the data type you want to validate the bare value as:
```css
@utility tab-* {
/* tab-1, tab-76, tab-971 */
tab-size: --value(integer);
}
```
### Arbitrary values
To support arbitrary values, use `--value([{type}])` (notice the square
brackets) to tell Tailwind which types are supported as an arbitrary
value:
```css
@utility tab-* {
/* tab-[1], tab-[76], tab-[971] */
tab-size: --value([integer]);
}
```
### Supporting theme values, bare values, and arbitrary values together
All three forms of the `--value(…)` function can be used within a rule
as multiple declarations, and any declarations that fail to resolve will
be omitted in the output:
```css
@theme {
--tab-size-github: 8;
}
@utility tab-* {
tab-size: --value([integer]);
tab-size: --value(integer);
tab-size: --value(--tab-size-*);
}
```
This makes it possible to treat the value differently in each case if
necessary, for example translating a bare integer to a percentage:
```css
@utility opacity-* {
opacity: --value([percentage]);
opacity: calc(--value(integer) * 1%);
opacity: --value(--opacity-*);
}
```
The `--value(…)` function can also take multiple arguments and resolve
them left to right if you don't need to treat the return value
differently in different cases:
```css
@theme {
--tab-size-github: 8;
}
@utility tab-* {
tab-size: --value(--tab-size-*, integer, [integer]);
}
@utility opacity-* {
opacity: calc(--value(integer) * 1%);
opacity: --value(--opacity-*, [percentage]);
}
```
### Negative values
To support negative values, register separate positive and negative
utilities into separate declarations:
```css
@utility inset-* {
inset: calc(--var(--spacing) * --value([percentage], [length]));
}
@utility -inset-* {
inset: calc(--var(--spacing) * --value([percentage], [length]) * -1);
}
```
## Modifiers
Modifiers are handled using the `--modifier(…)` function which works
exactly like the `--value(…)` function but operates on a modifier if
present:
```css
@utility text-* {
font-size: --value(--font-size-*, [length]);
line-height: --modifier(--line-height-*, [length], [*]);
}
```
If a modifier isn't present, any declaration depending on a modifier is
just not included in the output.
## Fractions
To handle fractions, we rely on the CSS `ratio` data type. If this is
used with `--value(…)`, it's a signal to Tailwind to treat the value +
modifier as a single value:
```css
/* The CSS `ratio` type is our signal to treat the value + modifier as a fraction */
@utility aspect-* {
/* aspect-square, aspect-3/4, aspect-[7/9] */
aspect-ratio: --value(--aspect-ratio-*, ratio, [ratio]);
}
```
This PR adds a new `@reference "…"` API as an replacement for the
previously added [`@import "…"
reference`](https://github.com/tailwindlabs/tailwindcss/pull/15228). The
motivation for a distinct at rule is that `@import` is already handled
outside of Tailwind in some scenarios (e.g. when using in combination
with postcss-import, other pre-processors, or frameworks like Svelte).
While our implementation of hijacking the `media` attribute _works in
this cases_, it can cause annoying linter issues because tooling build
around `@import` does not know about our behavior.
To fix this, we've decided to move this mode into a separate at rule
that is passed-through in the other tooling. Here's an example of how
this would look like in Svelte:
```svelte
<h1>Hello world!</h1>
<style>
@reference './theme.css';
h1 {
color: var(--theme-color);
}
</style>
```
With this change, the Svelte linter would not be detecting unused CSS
from the `theme.css` file as it would if we'd rely on `@import`.
This PR fixes an issue where using an `@utility` before it is defined,
and _if_ that `@utility` contains `@apply`, that it won't result in the
expected output. But results in an `@apply` rule that is not
substituted. Additionally, if you have multiple levels of `@apply`, we
have to make sure that everything is applied (no pun intended) in the
right order.
Right now, the following steps are taken:
1. Collect all the `@utility` at-rules (and register them in the system
as utilities).
2. Substitute `@apply` on the AST (including `@utility`'s ASTs) with the
content of the utility.
3. Delete the `@utility` at-rules such that they are removed from the
CSS output itself.
The reason we do it in this order is because handling `@apply` during
`@utility`
handling means that we could rely on another `@utility` that is defined
later
and therefore the order of the utilities starts to matter. This is not a
bad
thing, but the moment you import multiple CSS files or plugins, this
could
become hard to manage.
Another important step is that when using `@utility foo`, the
implementation creates a `structuredClone` from its AST when first using
the utility. The reason we do that is because `foo` and `foo!` generate
different output and we don't want to accidentally mutate the same AST.
This structured clone is the start of the problem in the linked issue
(#15501).
If we don't do the structured clone, then substituting the `@apply`
rules would work, but then `foo` and `foo!` will generate the same
output, which is bad.
The linked issue has this structure:
```css
.foo {
@apply bar;
}
@utility bar {
@apply flex;
}
```
If we follow the steps above, this would substitute `@apply bar` first,
which
results in:
```css
.foo {
@apply flex;
}
```
But the `bar` utility, was already cloned (and cached) so now we end up
with an `@apply` rule that is not substituted.
To properly solve this problem, we have to make sure that we collect all
the `@apply` at-rules, and apply them in the correct order. To do this,
we run a topological sort on them which ensures that all the
dependencies are applied before substituting the current `@apply`.
This means that in the above example, in order to process `@apply bar`,
we have to process the `bar` utility first.
If we run into a circular dependency, then we will throw an error like
before. You'll notice that the error message in this PR is updated to a
different spot. This one is a bit easier to grasp because it shows the
error where the circular dependency _starts_ not where it _ends_ (and
completes the circle). The previous message was not wrong (since it's a
circle), but now it's a bit easier to reason about.
Fixes: #15501
This PR is a tiny improvement to the `walk(…)` implementations, not a
super big
deal but thought about something and was pleasently surprised that it
did have
an impact.
The idea is twofold:
1. Reduce array allocations while walking to build a `path` to the
current node. This re-uses the existing `path` array and pushes the
current node before the recursive call and pops it afterwards. This way
we don't need to allocate a new array for each recursive call. Testing
this on Tailwind UI means ~14k fewer allocations.
2. Instead of always calling `.splice(…)`, we can directly update a
single value in the array if we are replacing a node with another node.
Testing on the Tailwind UI codebase, this results in:

---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
This PR ensures that if you are using an arbitrary value such as
`bg-[red` that it only compiles if it's a properly closed arbitrary
value.
Currently what happens is that it assumes the `]` is there, and cuts it
off. This then results in the `bg-[red` to be compiled as:
```css
.bg-\[red {
background-color: re;
}
```
Note how the `d` in `red` is cut off. That's the assumption that the `]`
is there.
This PR fixes that by ensuring that the arbitrary value is properly
closed.
Fixes: #15484
When we were porting all of the utilities from v3 to v4 we accidentally
used the wrong names for these two classes, so this PR fixes that and
corrects them back to the names used in v3.
| Before | After |
| --- | --- |
| `bg-round` | `bg-repeat-round` |
| `bg-space` | `bg-repeat-space` |
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
The utilities `place-content-between`, `place-content-around`, and
`place-content-evenly` are defined incorrectly. This PR fixes them.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
We don’t want utilities like `basis-prose`, `w-prose`, etc existing nor
a `@prose:*` variant. So we’re moving the theme key to `--max-width-*`
to align with the definition as it was in v3.
cc @adamwathan
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Resolves https://github.com/tailwindlabs/tailwindcss/discussions/15387
This PR changes the Chrome target to 111. We initially picked 120
because of the unnecessary `:dir()` down-leveling but we that was maybe
a bit too recent as it was causing some necessary prefixes to not be
generated (e.g. `-webkit-background-clip`).
This PR changes it to 111 which we require for the `color-mix()`
function. To work around the `:dir()` down-leveling we also disable the
`DirSelector` lightningcss feature which is used to control this
behavior:
https://sourcegraph.com/github.com/parcel-bundler/lightningcss/-/blob/src/selector.rs?L1964-1965
This PR renames the `--aspect-ratio` theme key to `--aspect`. This is to
match what we've done with other theme keys where they match the utility
names, like `--ease` and `--leading`.
```diff
@theme {
- --aspect-ratio-retro: 4 / 3;
+ --aspect-retro: 4 / 3;
}
```
Additionally, I've also converted the existing `aspect-video` static
utility to a theme value. This will allow people to override this
utility in their own projects—something that's not possible with static
utilities. This change feels appropriate since the video aspect ratio is
subjective, unlike other static utilities like `aspect-square`.
```css
@theme {
--aspect-video: 4 / 3; /* N64 baby! */
}
```
We changed how AST printing worked recently but forgot to update this.
Which causes us to print properties with a value of `undefined` in
Tailwind Play, Tailwind CSS IntelliSense, and our Language Server
(oops).
This PR fixes this by optimizing the AST before printing (which is what
toCss did previously)
Resolves#15315
It looks like we implemented this in Core but forgot to expose it from
the distributed package (the references are only used for testing
plugins internally right now). This exposes `flattenColorPalette` under
the old import path of `tailwindcss/lib/util/flattenColorPalette`.
## Test Plan
Added the following plugin to the Vite example and ensured it works as
expected:
```ts
import flattenColorPalette from 'tailwindcss/lib/util/flattenColorPalette'
import plugin from 'tailwindcss/plugin'
export default plugin(({ matchUtilities, theme }) => {
matchUtilities(
{
'hover-bg': (value) => {
return {
'&:hover': {
backgroundColor: value,
},
}
},
},
{ values: flattenColorPalette(theme('colors')) },
)
})
```
<img width="462" alt="Screenshot 2024-12-06 at 11 47 44"
src="https://github.com/user-attachments/assets/11163390-053e-4c6e-8cb9-ae67184ad594">
This PR improves the `@tailwindcss/postcss` integration by using direct
AST transformations between our own AST and PostCSS's AST. This allows
us to skip a step where we convert our AST into a string, then parse it
back into a PostCSS AST.
The only downside is that we still have to print the AST into a string
if we want to optimize the CSS using Lightning CSS. Luckily this only
happens in production (`NODE_ENV=production`).
This also introduces a new private `compileAst` API, that allows us to
accept an AST as the input. This allows us to skip the PostCSS AST ->
string -> parse into our own AST step.
To summarize:
Instead of:
- Input: `PostCSS AST` -> `.toString()` -> `CSS.parse(…)` -> `Tailwind
CSS AST`
- Output: `Tailwind CSS AST` -> `toCSS(ast)` -> `postcss.parse(…)` ->
`PostCSS AST`
We will now do this instead:
- Input: `PostCSS AST` -> `transform(…)` -> `Tailwind CSS AST`
- Output: `Tailwind CSS AST` -> `transform(…)` -> `PostCSS AST`
---
Running this on Catalyst, the time spent in the `@tailwindcss/postcss`
looks like this:
- Before: median time per run: 19.407687 ms
- After: median time per run: 11.8796455 ms
This is tested on Catalyst which roughly generates ~208kb worth of CSS
in dev mode.
While it's not a lot, skipping the stringification and parsing seems to
improve this step by ~40%.
Note: these times exclude scanning the actual candidates and only time
the work needed for parsing/stringifying the CSS from and into ASTs. The
actual numbers are a bit higher because of the Oxide scanner reading
files from disk. But since that part is going to be there no matter
what, it's not fair to include it in this benchmark.
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Closes#15219
This PR adds a new feature, `@import "…" reference` that can be used to
load Tailwind CSS configuration files without adding any style rules to
the CSS.
The idea is that you can use this in combination with your Tailwind CSS
root file when you need to have access to your full CSS config outside
of the main stylesheet. A common example is for Vue, Svelte, or CSS
modules:
```css
@import "./tailwind.css" reference;
.link {
@apply underline;
}
```
Importing a file as a reference will convert all `@theme` block to be
`reference`, so no CSS variables will be emitted. Furthermore it will
strip out all custom styles from the stylesheet. Furthermore plugins
registered via `@plugin` or `@config` inside reference-mode files will
not add any content to the CSS file via `addBase()`.
## Test Plan
Added unit test for when we handle the import resolution and when
`postcss-import` does it outside of Tailwind CSS. I also changed the
Svelte and Vue integration tests to use this new syntax to ensure it
works end to end.
---------
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
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>
This PR improves the performance of the `@tailwindcss/postcss` and
`@tailwindcss/vite` implementations.
The issue is that in some scenarios, if you have multiple `.css` files,
then all of the CSS files are ran through the Tailwind CSS compiler. The
issue with this is that in a lot of cases, the CSS files aren't even
related to Tailwind CSS at all.
E.g.: in a Next.js project, if you use the `next/font/local` tool, then
every font you used will be in a separate CSS file. This means that we
run Tailwind CSS in all these files as well.
That said, running Tailwind CSS on these files isn't the end of the
world because we still need to handle `@import` in case `@tailwind
utilities` is being used. However, we also run the auto source detection
logic for every CSS file in the system. This part is bad.
To solve this, this PR introduces an internal `features` to collect what
CSS features are used throughout the system (`@import`, `@plugin`,
`@apply`, `@tailwind utilities`, etc…)
The `@tailwindcss/postcss` and `@tailwindcss/vite` plugin can use that
information to decide if they can take some shortcuts or not.
---
Overall, this means that we don't run the slow parts of Tailwind CSS if
we don't need to.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
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>
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>
After the changes in #15201, our Windows CI started to fail. The problem
is that lightningcss now needs to convert `oklch` colors into the
`oklab` space to inline some `color-mix()` functions.
The problem, though, is that this calculation seems to have rounding
differences between macOS, Linux, and Windows. Since we still want to
_define the default color space in `oklch`_ and _use lightningcss as a
post-processor in our unit tests so we have a better coverage of the
output_, this PR attempts to fix the issue by adding a custom vitest
serializer. It will find usages of the `oklab()` function with arguments
that have lots of decimal places (at least 6 decimal places). What it
then does is simply cut off any excess decimal places to truncate the
output to 5 places. E.g.:
```diff
- oklab(62.7955% .224863 .125846 / .75);
+ oklab(62.7955% .22486 .12584 / .75);
```
## Test Plan
I updated the CI workflow file to make all three builds run in CI and
observed that they are now all green again.
<img width="609" alt="Screenshot 2024-11-27 at 14 54 52"
src="https://github.com/user-attachments/assets/73fe6da5-30e3-4fd4-83ea-115b1f1602a6">
This PR throws an error when we notice that an `layer(…)` in an
`@import` or `@media` is incorrect.
This hints the user to ensure that `layer(…)` in an `@import` should be
the first condition. In case of an `@media`, it should be an `@layer …`
instead.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Fixes https://github.com/tailwindlabs/tailwindcss/discussions/15184,
https://github.com/tailwindlabs/tailwindcss/issues/14955
There's a strange bug in Safari < 18 where mixing a color with
`transparent` or with a gray tone, the resulting color looks as if it's
been interpolated through a red-ish color.
Here's the same blue to transparent gradient in Safari 17 using OKLAB
and OKLCH for comparison:
<img width="747" alt="image"
src="https://github.com/user-attachments/assets/1cb09b00-0d84-4284-be34-103726d8af03">
In other browsers, both of these examples look identical.
This bug also shows up when using an opacity modifier right now because
we use `in oklch` in our `color-mix(…)` calls:
<img width="744" alt="image"
src="https://github.com/user-attachments/assets/b029c5f1-0c5c-4119-80ba-dfeabe25927e">
This PR updates all of the affected places in Tailwind to use `in oklab`
instead of `in oklch` which then renders everything as expected in all
browsers.
The big unfortunate change here is changing the default behavior of
gradient utilities like `bg-linear-to-r` to use `in oklab` instead of
`in oklch`. This means you get muddier gradients by default when
creating a gradient between two regular colors (no transparent or gray),
like how they looked in v3:
<img width="740" alt="image"
src="https://github.com/user-attachments/assets/d02e7596-4c99-4ba3-b929-d2db4911c8e9">
This feels worth it though to avoid people getting bitten by this Safari
bug without realizing it, and people can always opt in to using OKLCH
with classes like `bg-linear-to-r/oklch`. The nice thing about making
this opt-in is that no one will opt-in to this when using transparent or
gray because it won't make things look any different/better, and the
only places where it does make things look better _do_ work as expected
in Safari anyways.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Fixes#15146.
This PR updates the `w-*`, `max-w-*`, `min-w-*`, and `basis-*` utilities
to make sure that `--spacing-*` values are preferred over
`--container-*` values when there is a conflict.
Given this theme configuration:
```css
@theme {
--spacing-sm: 8px;
--container-sm: 256px;
}
```
…utilities like `max-w-sm` will use `8px` instead of `256px` after this
change.
Users can still be explicit about the value they want to use if they've
introduced a naming collision like this by using our variable shorthand
like `max-w-(--container-sm)`.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Closes#15160
We need to set browser targets for each browser individually to see
vendor prefixes created for each browser.
Exact values are up for discussion, this first pass is taken from
@adamwathan's comments in
https://github.com/tailwindlabs/tailwindcss/issues/15160
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
Fixes#15144.
Weird bug in Safari that breaks 3D transforms when using registered
custom properties registered with the "<transform-function>" type:
https://bugs.webkit.org/show_bug.cgi?id=283487
Declaring them as just "*" fixes it with no apparent downside since
transitioning these 3D transforms still works, and usually
transitions/animations are the reason you'd type these properties.
Evidence of rotations looking the same in all browsers here:

---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
This PR fixes an issue where the `.group` and `.peer` classes didn't get
prefixed if you are using the `prefix(…)` option.
Before this change, `tw:group-hover:flex`, generated:
```css
.tw\\:group-hover\\:flex {
&:is(:where(.group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
But now it generates:
```css
.tw\\:group-hover\\:flex {
&:is(:where(.tw\\:group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
Or as a diff, it might be more clear:
```diff
.tw\\:group-hover\\:flex {
- &:is(:where(.group):hover *) {
+ &:is(:where(.tw\\:group):hover *) {
@media (hover: hover) {
display: flex;
}
}
}
```
Fixes: #15172
Fixes https://github.com/tailwindlabs/tailwindcss/issues/15107.
Previously we were generating `word-break: break-keep` when it should be
`word-break: keep-all`.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Closes#15071
This PR reverts the changes in #15036 which add consistent base styles
for buttons and form controls to Preflight.
While this felt like a good idea (for the reasons explained in that PR),
practically this is just too disruptive of a change for people upgrading
from v3 to v4.
While updating some of our projects to v4 we found ourselves adding
classes to undo styles more often than we expected, and it also felt
inconsistent to have to use a different set of classes to style a link
or a button when we wanted them to look the same.
We also decided it feels a little strange that you could change the
border color of an element without ever specifying that it should have a
border, for example this just feels a little wrong:
```html
<button class="border-blue-500">
```
We also needed to set a default `color-scheme` value for any of this
stuff to work which breaks the ability to use the `color-scheme` meta
tag.
Since this change was a fairly major breaking change and we aren't
feeling much benefit from it, it doesn't feel worth making this change
for v4.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
We weren't resetting the `--tw-space-x-reverse` and
`--tw-space-y-reverse` state in the `space-x/y-{number}` utilities which
broke code assuming that `md:space-x-3` would no longer be reversed.
This PR fixes that.
---------
Co-authored-by: Adam Wathan <adam.wathan@gmail.com>
These utilities are deprecated (and were removed) but we're brining them
back so they keep working:
- `flex-grow-*`
- `flex-shrink-*`
- `decoration-slice`
- `decoration-clone`
- `overflow-ellipsis`