This PR adds `bg-{position,size}-*` utilities that support arbitrary
values. This exist as the new preferred version of something like this:
```
bg-[120px_120px]
```
Is it size or position (hint: it's the 2nd one).
To override it you'd have to provide a data type:
```
bg-[size:120px_120px]
```
Now you can be more explicit and have better intellisense by writing
these:
```
bg-position-[120px_120px]
bg-size-[120px_120px]
```
Fixes#17357
This affects the CDN and Play
Now candidates like these no longer parse and emit CSS:
- `[--foo:1rem;--bar:2rem]`
- `[&{color:red}]:flex`
- `data-[a]{color:red}foo[a]:flex`
This replaces the `scripting`, `scripting-none`, and `scripting-initial`
variants with one `noscript` variant that matches the name of the HTML
`<noscript>` element. The previous `scripting` can then be represented
as `not-noscript` e.g. `not-noscript:flex`.
We’re using this naming for `mask-*` and `mask-radial-at-*` position
utilities and we want to be consistent. The old ones for
`background-position` will stay but are deprecated
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR adds a new source detection feature: `@source not "…"`. It can
be used to exclude files specifically from your source configuration
without having to think about creating a rule that matches all but the
requested file:
```css
@import "tailwindcss";
@source not "../src/my-tailwind-js-plugin.js";
```
While working on this feature, we noticed that there are multiple places
with different heuristics we used to scan the file system. These are:
- Auto source detection (so the default configuration or an `@source
"./my-dir"`)
- Custom sources ( e.g. `@source "./**/*.bin"` — these contain file
extensions)
- The code to detect updates on the file system
Because of the different heuristics, we were able to construct failing
cases (e.g. when you create a new file into `my-dir` that would be
thrown out by auto-source detection, it'd would actually be scanned). We
were also leaving a lot of performance on the table as the file system
is traversed multiple times for certain problems.
To resolve these issues, we're now unifying all of these systems into
one `ignore` crate walker setup. We also implemented features like
auto-source-detection and the `not` flag as additional _gitignore_ rules
only, avoid the need for a lot of custom code needed to make decisions.
High level, this is what happens after the now:
- We collect all non-negative `@source` rules into a list of _roots_
(that is the source directory for this rule) and optional _globs_ (that
is the actual rules for files in this file). For custom sources (i.e
with a custom `glob`), we add an allowlist rule to the gitignore setup,
so that we can be sure these files are always included.
- For every negative `@source` rule, we create respective ignore rules.
- Furthermore we have a custom filter that ensures files are only read
if they have been changed since the last time they were read.
So, consider the following setup:
```css
/* packages/web/src/index.css */
@import "tailwindcss";
@source "../../lib/ui/**/*.bin";
@source not "../../lib/ui/expensive.bin";
```
This creates a git ignore file that (simplified) looks like this:
```gitignore
# Auto-source rules
*.{exe,node,bin,…}
*.{css,scss,sass,…}
{node_modules,git}/
# Custom sources can overwrite auto-source rules
!lib/ui/**/*.bin
# Negative rules
lib/ui/expensive.bin
```
We then use this information _on top of your existing `.gitignore`
setup_ to resolve files (i.e so if your `.gitignore` contains rules e.g.
`dist/` this line is going to be added _before_ any of the rules lined
out in the example above. This allows negative rules to allow-list your
`.gitignore` rules.
To implement this, we're rely on the `ignore` crate but we had to make
various changes, very specific, to it so we decided to fork the crate.
All changes are prefixed with a `// CHANGED:` block but here are the
most-important ones:
- We added a way to add custom ignore rules that _extend_ (rather than
overwrite) your existing `.gitignore` rules
- We updated the order in which files are resolved and made it so that
more-specific files can allow-list more generic ignore rules.
- We resolved various issues related to adding more than one base path
to the traversal and ensured it works consistent for Linux, macOS, and
Windows.
## Behavioral changes
1. Any custom glob defined via `@source` now wins over your `.gitignore`
file and the auto-content rules.
- Resolves#16920
3. The `node_modules` and `.git` folders as well as the `.gitignore`
file are now ignored by default (but can be overridden by an explicit
`@source` rule).
- Resolves#17318
- Resolves#15882
4. Source paths into ignored-by-default folders (like `node_modules`)
now also win over your `.gitignore` configuration and auto-content
rules.
- Resolves#16669
5. Introduced `@source not "…"` to negate any previous rules.
- Resolves#17058
6. Negative `content` rules in your legacy JavaScript configuration
(e.g. `content: ['!./src']`) now work with v4.
- Resolves#15943
7. The order of `@source` definitions matter now, because you can
technically include or negate previous rules. This is similar to your
`.gitingore` file.
9. Rebuilds in watch mode now take the `@source` configuration into
account
- Resolves#15684
## Combining with other features
Note that the `not` flag is also already compatible with [`@source
inline(…)`](https://github.com/tailwindlabs/tailwindcss/pull/17147)
added in an earlier commit:
```css
@import "tailwindcss";
@source not inline("container");
```
## Test plan
- We added a bunch of oxide unit tests to ensure that the right files
are scanned
- We updated the existing integration tests with new `@source not "…"`
specific examples and updated the existing tests to match the subtle
behavior changes
- We also added a new special tag `[ci-all]` that, when added to the
description of a PR, causes the PR to run unit and integration tests on
all operating systems.
[ci-all]
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Prepare the 4.0.16 release.
~~Also added a commit to mark the `--value('…')` and `--modifier('…')`
with literals strings as an experimental feature (aka not shipped in
this PR). But we can revert that commit if we still want to ship it in
4.0.16 instead of 4.1.~~
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
See #17360
This PR updates the `marker` variant to also target the marker present
in `<summary>` elements in WebKit browsers. Chromium uses `::marker` and
is therefore already covered.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Fixes#17332
This PR ensures that keyframes are emitted even when they are referenced
following a comma, e.g.:
```css
@theme {
--animate-test: 500ms both fade-in, 1000ms linear 500ms spin infinite;
/* ^ */
@keyframes fade-in {
from {
opacity: 0%;
}
to {
opacity: 100%;
}
}
}
```
## Test plan
Added a unit test to capture the issue from #17332
Throw an error if the input and output file for the CLI are identical.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Closes#17339
This PR fixes an issue that caused changes to `@import`-ed CSS files to
no longer rebuild the stylesheet after a change was made to a template
file.
The change in the template file causes a fast-path in the Vite plugin
now after changes in 4.0.8: _partial rebuilds_. For that branch we do
not need to re-evaluate your input CSS since we know only the candidate
list changed. However, we still need to emit all build dependencies as
via `addWatchFile(…)`, otherwise Vite will not correctly register
updates for these dependencies anymore.
## Test plan
- Updated the kitchen-sink Vite update tests to ensure that an
`@import`-ed CSS file can be updated even after a partial rebuild.
- Ensure this works in our Vite playground
This PR adds support for literal values inside the `--value('…')` and
`--modifier('…')` functions. This allows you to safelist some known
values you want to use:
E.g.:
```css
@utility tab-* {
tab-size: --value('revert', 'initial');
}
```
This allows you to use `tab-revert` and `tab-initial` for example.
<!--
👋 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
-->
Closes#17194.
This reverts commit d6d913ec39e2a4cc0a70e9d21c484c6ed95d40ae.
The initial fix does breaks older versions of Chrome (where text won't
render with a color for the placeholder at all anymore) and the usage of
the _relative colors_ features also means it'll require a much newer
version of Safari/Firefox/Chrome to work correctly. The implementation
was also wrong as it always set alpha to the specific percent instead of
applying it additively (note that this can be fixed with `calc(alpha *
opacity)` though).
Instead we decided to fix this by adding a `@supports` query to
Preflight that only targets browsers that aren't affected by the crash.
We currently use the following workaround:
```css
/*
Set the default placeholder color to a semi-transparent version of the current text color in browsers that do not
crash when using `color-mix(…)` with `currentColor`. (https://github.com/tailwindlabs/tailwindcss/issues/17194)
*/
@supports (not (-webkit-appearance: -apple-pay-button)) /* Not Safari */ or
(contain-intrinsic-size: 1px) /* Safari 17+ */ {
::placeholder {
color: color-mix(in oklab, currentColor 50%, transparent);
}
}
```
## Test plan
When testing the `color-mix(currentColor)` vs `oklab(from currentColor
…)` we created the following support matrix. I'm extending it with _our
fix_ which is the fix ended up using:
| Browser | Version | `color-mix(… currentColor …)` | `oklab(from
currentColor …)` | `@supports { color-mix(…) }` |
| ------- | ------- | ----------------------------- |
---------------------------- | ------- |
| Chrome | 111 | ❌ | ❌ | ❌ |
| Chrome | 116 | ✅ | ❌ | ✅ |
| Chrome | 131+ | ✅ | ✅ | ✅ |
| Safari | 16.4 | 💥 | ❌ | ❌ |
| Safari | 16.6+ | ✅ | ❌ | ❌ |
| Safari | 18+ | ✅ | ✅ | ✅ |
| Firefox | 128 | ✅ | ❌ | ✅ |
| Firefox | 133 | ✅ | ✅ | ✅ |
Note that on Safari 16, this change makes it so that the browser does
not crash yet it still won't work either. That's because now the browser
will fall back to the default placeholder color instead. We used the
following play to test the fix: https://play.tailwindcss.com/RF1RYbZLKY
Fixes#17288
This PR fixes an issue where changes in template files that _only mark a
new CSS variable as used_ was not causing the CSS file to rebuilds.
This also fixes a flaky integration test that was caused by a missing
`await` line on the final assertion (causing it to sometimes run the
assertion in time while the test runner was still running).
## Test plan
Turns out we already had an integration test for this but it wasn't
correctly running due to the missing await.
Closes#16945
This PR changes the `--theme(…)` function now return CSS `var(…)`
definitions unless used in places where `var(…)` is not valid CSS (e.g.
in `@media (width >= theme(--breakpoint-md))`):
```css
/* input */
@theme {
--color-red: red;
}
.red {
color: --theme(--color-red);
}
/* output */
:root, :host {
--color-red: red;
}
.red {
color: var(--color-red);
}
```
Furthermore, this adds an `--theme(… inline)` option to the `--theme(…)`
function to force the resolution to be inline, e.g.:
```css
/* input */
@theme {
--color-red: red;
}
.red {
color: --theme(--color-red inline);
}
/* output */
.red {
color: red;
}
```
This PR also changes preflight and the default theme to use this new
`--theme(…)` function to ensure variables are prefixed correctly.
## Test plan
- Added unit tests and a test that pulls in the whole preflight under a
prefix theme.
Closes#17259
This PR now also updates the MacOS x64 build to use `bun-baseline`,
meaning all x64 builds now use baseline for the improved hardware
compatibility.
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
This PR fixes a bug in the handling of `@utility`. Essentially if you
had a declaration where you used a `--modifier(…)` _and_ a `--value(…)`
and both caused the declaration to be removed, the declaration after the
current one would be removed as well.
This happened because 2 reasons:
1. Once we removed the declaration when we handled `--modifier(…)`, we
didn't stop the walk and kept going.
2. The `replaceWith(…)` code allows you to call the function multiple
times but immediately mutates the AST. This means that if you call it
multiple times that you are potentially removing / updating nodes
followed by the current one.
E.g.:
```css
@utility mask-r-* {
--mask-right: linear-gradient(to left, transparent, black --value(percentage));
--mask-right: linear-gradient(
to left,
transparent calc(var(--spacing) * --modifier(integer)),
black calc(var(--spacing) * --value(integer))
);
mask-image: var(--mask-linear), var(--mask-radial), var(--mask-conic);
}
```
If this is used as `mask-r-10%`, then the first definition of
`--mask-right` is kept, but the second definition of `--mask-right` is
deleted because both `--modifier(integer)` and `--value(integer)` do not
result in a valid value.
However, the `mask-image` declaration was also removed because the
`replaceWith(…)` function was called twice. Once for
`--modifier(integer)` and once for `--value(integer)`.
# Test plan
1. Added a test to cover this case.
2. Existing tests pass.
3. Added a hard error if we call `replaceWith(…)` multiple times.
It was added in #2729 to override line heights set on the body by
modern-normalize. However, it appears that modern-normalize never
included any line-height definitions—only a font-family rule was
present.
Ref:
https://github.com/sindresorhus/modern-normalize/blob/v1.1.0/modern-normalize.css
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Fixes#7929 and #12916
This PR adds [safe alignment
utilities](https://www.stefanjudis.com/today-i-learned/safe-unsafe-alignment-in-css-flexbox/)
to Tailwind 4. I opted to include them for every justify/align
content/items/self property, but only for the `end` and `center` values.
I know that it doesn't make sense for `start` (as the point of safe
alignment is to fall back to `start` when it overflows), but I'm not
sure about `space-between`, `space-around`, or other values. I certainly
never encountered a situation where I needed `safe` with those.
Closes#17194
This PR works around a crash when rendering opacity on `currentColor`
(as used by the placeholder styles in preflight) on Safari 16.4 and
Safari 16.5. Unfortunately it seems that the [`color-mix(…)` function is
not compatible with `currentColor` for these versions of
Safari](https://stackoverflow.com/questions/76436497/the-color-mix-property-involving-currentcolor-causes-safari-to-crash).
We tried a few different ways to work around this without success:
- Using an `@supports` media query to target these Safari versions and
overwriting the placeholder still makes these browsers crash.
- Changing the way we apply opacity to `currentColor` in core doesn't
seem to work for non-placeholder values:
https://github.com/tailwindlabs/tailwindcss/issues/17194#issuecomment-2728949181
However, a wrong opacity is still better than a complete browser crash.
The work-around of using the `oklab(…)` function does seem to work for
`::placeholder` styles in preflight though according to our testing so
this PR applies this change to preflight.
## Test plan
- See https://play.tailwindcss.com/WSsSTLHu8h?file=css
- Tested on Chrome/Safari 16.4/Safari 18.3/Firefox
<img width="564" alt="Screenshot 2025-03-17 at 11 32 47"
src="https://github.com/user-attachments/assets/cfd0db71-f39a-4bc0-bade-cea70afe50ae"
/>
This PR fixes an issue where arbitrary values such as
`border-[12px_4px]` were incorrectly producing `border-color` instead of
`border-width` values.
To solve it, I extended the `<line-width>` check to make sure that every
part of the value is a valid `<line-width>`.
In order for a `line-width` to be valid, every part should be one of:
1. A keyword: `thin`, `medium`, `thick`
2. A length: `12px`
3. A number: `0`
Fixes: #17221
# Test plan
1. Added test to verify this works
2. All existing tests pass
Closes#17162Closes#17163Closes#17164Closes#17165Closes#17166Closes#17167
Noticed that there was a second place pulling in the lightningcss
version numbers that wasn't covered by the previous upgrade PR.
Thankfully the APIs of the node bindings are still compatible.
To avoid this mistake in the future I also exported these sub-packages
as a workspace dependency so all the version strings appear right next
to each other.
This PR adds a new experimental feature that can be used to force-inline
utilities based on an input string. The idea is that all utilities
matching the source string will be included in your CSS:
```css
/* input.css */
@source inline('underline');
/* output.css */
.underline {
text-decoration: underline;
}
```
Additionally, the source input is brace-expanded, meaning you can use
one line to inline a whole namespace easily:
```css
/* input.css */
@source inline('{hover:,}bg-red-{50,{100..900..100},950}');
/* output.css */
.bg-red-50 {
background-color: var(--color-red-50);
}
.bg-red-100 {
background-color: var(--color-red-100);
}
.bg-red-200 {
background-color: var(--color-red-200);
}
.bg-red-300 {
background-color: var(--color-red-300);
}
.bg-red-400 {
background-color: var(--color-red-400);
}
.bg-red-500 {
background-color: var(--color-red-500);
}
.bg-red-600 {
background-color: var(--color-red-600);
}
.bg-red-700 {
background-color: var(--color-red-700);
}
.bg-red-800 {
background-color: var(--color-red-800);
}
.bg-red-900 {
background-color: var(--color-red-900);
}
.bg-red-950 {
background-color: var(--color-red-950);
}
@media (hover: hover) {
.hover\\:bg-red-50:hover {
background-color: var(--color-red-50);
}
.hover\\:bg-red-100:hover {
background-color: var(--color-red-100);
}
.hover\\:bg-red-200:hover {
background-color: var(--color-red-200);
}
.hover\\:bg-red-300:hover {
background-color: var(--color-red-300);
}
.hover\\:bg-red-400:hover {
background-color: var(--color-red-400);
}
.hover\\:bg-red-500:hover {
background-color: var(--color-red-500);
}
.hover\\:bg-red-600:hover {
background-color: var(--color-red-600);
}
.hover\\:bg-red-700:hover {
background-color: var(--color-red-700);
}
.hover\\:bg-red-800:hover {
background-color: var(--color-red-800);
}
.hover\\:bg-red-900:hover {
background-color: var(--color-red-900);
}
.hover\\:bg-red-950:hover {
background-color: var(--color-red-950);
}
}
```
This feature is also compatible with the `not` keyword that we're about
to add to `@source "…"` in a follow-up PR. This can be used to set up an
ignore list purely in CSS. The following code snippet, for example, will
ensure that the `.container` utility is never created:
```css
@theme {
--breakpoint-sm: 40rem;
--breakpoint-md: 48rem;
--breakpoint-lg: 64rem;
--breakpoint-xl: 80rem;
--breakpoint-2xl: 96rem;
}
@source not inline("container");
@tailwind utilities;
```
## Test plan
- See added unit tests
- The new brace expansion library was also benchmarked against the
popular `braces` library:
```
clk: ~3.96 GHz
cpu: Apple M4 Max
runtime: bun 1.1.34 (arm64-darwin)
benchmark avg (min … max) p75 / p99 (min … top 1%)
-------------------------------------------
-------------------------------
braces 31.05 ms/iter 32.35 ms █ █
(28.14 ms … 36.35 ms) 35.14 ms ██ █
( 0.00 b … 116.45 mb) 18.71 mb ██████▁▁▁██▁█▁██▁█▁▁█
./brace-expansion 19.34 ms/iter 21.69 ms █
(12.53 ms … 26.63 ms) 25.53 ms ▅ ▅ █ █
( 0.00 b … 114.13 mb) 11.86 mb █▁▅▁██▁▅█▅█▅▁█▅█▅▅▁▅█
┌ ┐
╷┌────┬─┐ ╷
braces ├┤ │ ├─────┤
╵└────┴─┘ ╵
╷ ┌────┬───┐ ╷
./brace-expansion ├────────┤ │ ├───────┤
╵ └────┴───┘ ╵
└ ┘
12.53 ms 23.84 ms 35.14 ms
```
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Fixes#16636
This PR enables URL rebasing for PostCSS. Furthermore it fixes an issue
where transitive imports rebased against the importer CSS file instead
of the input CSS file. While fixing this we noticed that this is also
broken in Vite right now and that our integration test swallowed that
when testing because it did not import any Tailwind CSS code and thus
was not considered a Tailwind file.
## Test plan
- Added regression integration tests
- Also validated it against the repro of
https://github.com/tailwindlabs/tailwindcss/issues/16962:
<img width="1149" alt="Screenshot 2025-03-05 at 16 41 01"
src="https://github.com/user-attachments/assets/85396659-d3d0-48c0-b1c7-6125ff8e73ac"
/>
---------
Co-authored-by: Robin Malfait <malfait.robin@gmail.com>
Co-authored-by: Jordan Pittman <jordan@cryptica.me>
Closes#16973
Declaration values of `undefined` are an implementation detail and
skipped when printing the CSS. Thus, these should not count towards the
sort order at a..
## Test plan
- See added regression test
Closes#16877
This PR works around #16877 by not registering `.svg` files containing a
`#` or `?` as a watch dependency for now.
## Test plan
- Add a file to the Vite playground called `src/c#.svg`
- Observe Vite no longer prints errors
We recently fixed an issue
(https://github.com/tailwindlabs/tailwindcss/issues/16664) so that we
could remove the `!important` on CSS variables. The reason we did that
is because Google Chrome is showing a warning in the devtools styles
panel that this is invalid. However, this _is_ valid and the code
actually works as expected.
If we look at the CSS spec for this:
> Note: Custom properties can contain a trailing `!important`, but this
is automatically removed from the property’s value by the CSS parser,
and makes the custom property "important" in the CSS cascade. In other
words, the prohibition on top-level "!" characters does not prevent
`!important` from being used, as the `!important` is removed before
syntax checking happens.
>
> — https://www.w3.org/TR/css-variables-1/#syntax
So given this input:
```css
@import "tailwindcss";
body {
--text-color: var(--color-white) !important;
--bg-color: var(--color-blue-950) !important;
/* Direct usage */
background-color: var(--bg-color);
/* Usage inside other functions as-if the `!important` is in the middle instead of the end */
color: color-mix(in oklab, var(--text-color) 75%, transparent);
}
```
You will notice that everything works as expected, but if you look at
the Styles panel in Chrome for the `<body>` element, you will see an
incorrect warning. (At least that's what you used to see, I updated
Chrome and everything renders fine in devtools).
Play: https://play.tailwindcss.com/BpjAJ6Uxg3?file=css
This change reverts the "fix" for:
https://github.com/tailwindlabs/tailwindcss/issues/16664. @winchesHe you
were the original person that opened the issue so this info might be
useful to you as well. Can you verify that the Play link above does work
as expected for you?
Fixes: #16810
Fixes#16935
This PR fixes an issue where the order of how `@apply` was resolved was
incorrect for nested rules. Consider this example:
```css
.rule {
@apply underline;
.nested-rule {
@apply custom-utility;
}
}
@utility custom-utility {
@apply flex;
}
```
The way we topologically sort these, we end up with a list that looks
roughly like this:
```css
.rule {
@apply underline;
.nested-rule {
@apply custom-utility;
}
}
@utility custom-utility {
@apply flex;
}
.nested-rule {
@apply custom-utility;
}
```
As you can see here the nested rule is now part of the top-level list.
This is correct because we first have to substitute the `@apply` inside
the `@utility custom-utility` before we can apply the `custom-utility`
inside `.nested-rule`. However, because we were using a regular AST walk
and because the initial `.rule` also contains the `.nested-rule` as
child, we would first substitute the `@apply` inside the `.nested-rule`,
causing the design-system to force resolve (and cache) the wrong value
for `custom-utility`.
Because the list is already flattened, we do not need to recursively
look into child declarations when we traverse the sorted list. This PR
changes it to use a regular `for` loop instead of the `walk`.
## Test plan
- Added a regression test
- Rest of tests still green
Part-of #16926
I noticed that `outline-hidden` would not set `--tw-outline-style`
(contrary to `outline-none`), thus stacking it with other outline
classes won't work as expected: https://play.tailwindcss.com/Y0lPGgekYh
Resolves#15170.
This PR adds support for bare integer values to the `col-*` and `row-*`
utilities:
```css
.col-5 {
grid-column: 5;
}
.row-6 {
grid-row: 6;
}
```
These properties are shorthands for
`grid-column-start`/`grid-column-end` and
`grid-row-start`/`grid-row-end`, so using a bare integer value ends up
being a shortcut for:
```css
.col-5 {
grid-column-start: 5;
grid-column-end: auto;
}
```
…which makes these basically work like an alternative to `col-start-*`
and `row-start-*`.
These support negative values like `-col-6` as well, which also
technically extends to arbitrary values like `-col-[6/span_2]` now even
though that is a junk value. I've decided not to guard against that
though and just consider it user error to keep the implementation
simple.
---------
Co-authored-by: Adam Wathan <4323180+adamwathan@users.noreply.github.com>
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Closes#16829
We were only adding keyframes used in variables starting with
`--animate` (without adding a potential prefix).
## Test plan
- Added a unit test
This adds two variants for the
[`scripting`](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/scripting)
media query. `noscript` for when JavaScript is disabled and `scripting`
for when it's enabled.
---------
Co-authored-by: Philipp Spiess <hello@philippspiess.com>
Resolves#16821
This PR removes a special case in the `not-*` variant compound that
removed `:is(…)` if it was the only part of the inversed selector list.
While in-theory this makes sense, `:is(…)` accepts a _forgiving_
selector list where as `:not(…)` does not. See the [last point
here](https://developer.mozilla.org/en-US/docs/Web/CSS/:not#description).
This is an issue specifically in combinations with variants that have
selectors that are not supported by all browsers yet, for example
`:open`.
It seems to be the most expected to simply keep the `:is(…)` here in any
case.
## Test plan
- Ensured the repro form #16821 now also works in browsers that do not
support `:open` (Safari and Firefox at the time of writing this):
<img width="484" alt="Screenshot 2025-02-26 at 15 36 22"
src="https://github.com/user-attachments/assets/f3391693-895b-4e44-8566-95e2960ec4e3"
/>