Skip to content

Don't space out and/or/not inside function calls in supports-[…] variants - #20420

Merged
RobinMalfait merged 9 commits into
tailwindlabs:mainfrom
webdevelopersrinu:fix/supports-selector-keywords
Aug 14, 2026
Merged

Don't space out and/or/not inside function calls in supports-[…] variants#20420
RobinMalfait merged 9 commits into
tailwindlabs:mainfrom
webdevelopersrinu:fix/supports-selector-keywords

Conversation

@webdevelopersrinu

Copy link
Copy Markdown
Contributor

Summary

The supports-[…] variant works around a Chrome bug where @supports (a)or(b)
is invalid by spacing out the and, or, and not keywords. However, the
replacement is applied to the entire value, including the inside of function
calls, where these words can be part of a selector.

For example, supports-[selector(a:not(.foo))]:flex generates:

@supports selector(a: not (.foo))

The selector a: not (.foo) is unparsable, so a condition that is true in
every browser silently becomes false and the utility never applies. The same
happens to class names like .and or .or inside selector(…).

This PR only spaces out the keywords at the condition level: parens preceded by
an identifier (other than the keywords themselves) start a function call, and
everything inside is left as-is. The Chrome workaround still applies to the
condition itself, e.g. supports-[(display:grid)or(display:flex)] still
becomes @supports (display: grid) or (display: flex).

Test plan

  • Added a test covering selector(a:not(.foo)), class names .and/.or
    inside selector(…), the Chrome (a)or(b) workaround, and a top-level
    not(…) condition.
  • pnpm vitest run packages/tailwindcss/src/variants.test.ts — 102 passed.

@webdevelopersrinu
webdevelopersrinu requested a review from a team as a code owner August 14, 2026 13:41
……]` variants

The `supports-[…]` variant spaces out the `and`, `or`, and `not`
keywords to work around a Chrome bug where `@supports (a)or(b)` is
invalid. The replacement was applied to the entire value, including
inside function calls where these words can be part of a selector:
`supports-[selector(a:not(.foo))]` generated
`@supports selector(a: not (.foo))`, an unparsable selector, so the
condition silently never matched.

Keywords are now only spaced out at the condition level; the contents
of function calls like `selector(…)` are left as-is.
@webdevelopersrinu
webdevelopersrinu force-pushed the fix/supports-selector-keywords branch from 62f3b1e to 56e2878 Compare August 14, 2026 13:42
@coderabbitai

coderabbitai Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: f76ad5c0-0a66-4d4e-b8e1-769d26d73477

📥 Commits

Reviewing files that changed from the base of the PR and between 368f3a1 and f58dc96.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • packages/tailwindcss/src/variants.test.ts
  • packages/tailwindcss/src/variants.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • CHANGELOG.md
  • packages/tailwindcss/src/variants.ts
  • packages/tailwindcss/src/variants.test.ts

Walkthrough

The supports variant now parses condition values into an AST. It spaces and, or, and not only at the top level and preserves nested selector() content. Regression tests cover compound, negated, nested, quoted, escaped, and token-like function conditions. The changelog includes an Unreleased entry.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly describes the main change: preserving compact and, or, and not tokens inside function calls.
Description check ✅ Passed The description directly explains the bug, the implementation change, and the tests for the supports-[…] variants.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 456c12b3-5119-474d-83dd-28ed260d9e81

📥 Commits

Reviewing files that changed from the base of the PR and between 021b7fe and 56e2878.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • packages/tailwindcss/src/variants.test.ts
  • packages/tailwindcss/src/variants.ts

Comment thread packages/tailwindcss/src/variants.ts Outdated
@greptile-apps

greptile-apps Bot commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the current parser and recursive traversal address all three previously reported issues.

Reviews (6): Last reviewed commit: "use proper walk + bail when we see `sele..." | Re-trigger Greptile

Comment thread packages/tailwindcss/src/variants.ts Outdated
…conditions

Tokenize identifiers whole so function names like `foo-not(…)` are not
mistaken for the `not` keyword, and skip quoted strings so parens
inside values like `selector([data-foo="("])` don't unbalance the
function-depth tracking.
Comment thread packages/tailwindcss/src/variants.ts Outdated
webdevelopersrinu and others added 3 commits August 14, 2026 19:48
…ions

A lone escaped paren outside a string (e.g. a class named `.foo\(` in
`selector(…)`) unbalanced the function-depth tracking, leaving a
following top-level `or` unspaced.
@RobinMalfait
RobinMalfait enabled auto-merge (squash) August 14, 2026 19:12
Comment thread packages/tailwindcss/src/variants.ts Outdated

@RobinMalfait RobinMalfait left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

I updated the code to make use of an existing value parser and mutating the AST, instead of using a bunch of regexes.

@RobinMalfait
RobinMalfait merged commit 90f8ff4 into tailwindlabs:main Aug 14, 2026
9 checks passed
@webdevelopersrinu

Copy link
Copy Markdown
Contributor Author

Thank you @RobinMalfait for the review and the refactor to the value parser that approach is much cleaner than the regex tokenizer, and I learned a lot comparing the two. Happy to see both fixes land

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants