Skip to content

Fix in-* variant generating invalid CSS with relative arbitrary selectors - #20424

Open
koreahghg wants to merge 2 commits into
tailwindlabs:mainfrom
koreahghg:fix/in-variant-relative-selector
Open

Fix in-* variant generating invalid CSS with relative arbitrary selectors#20424
koreahghg wants to merge 2 commits into
tailwindlabs:mainfrom
koreahghg:fix/in-variant-relative-selector

Conversation

@koreahghg

Copy link
Copy Markdown
Contributor

Summary

in-* builds its selector as :where(…) &, but unlike :has(), :where() doesn't accept relative selectors (e.g. >img, +img, ~img).

This meant in-[>img]:flex silently produced:

:where() .in-\[\>img\]\:flex {
  display: flex;
}

An empty, invalid :where() that every browser drops the rule for — the utility is silently non-functional. not-*, group-*, and peer-* already guard against this exact case (they bail out and generate no CSS for a relative arbitrary selector), but in-* was missing the same guard.

This adds the same one-line guard already used by not, group, and peer to the in compound variant.

Test plan

  • Added a regression test to in-*'s existing test block in variants.test.ts asserting in-[>img]:flex, in-[+img]:flex, and in-[~img]:flex all produce no output, mirroring the existing peer-[>img]:flex / group-[>img]:flex assertions.
  • pnpm vitest run — all 5007 existing tests in the tailwindcss package pass, no regressions.

…ectors

`in-*` builds its selector as `:where(…) &`, but unlike `:has()`, `:where()`
doesn't accept relative selectors (e.g. `>img`, `+img`, `~img`). This meant
`in-[>img]:flex` silently produced an empty, invalid `:where()` that browsers
drop the rule for, instead of being rejected like `not-[>img]`, `group-[>img]`,
and `peer-[>img]` already are.

Add the same relative-selector guard already used by `not`, `group`, and `peer`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@koreahghg
koreahghg requested a review from a team as a code owner August 20, 2026 01:08
@coderabbitai

coderabbitai Bot commented Aug 20, 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: e6769337-7024-4486-93a9-9627215b8887

📥 Commits

Reviewing files that changed from the base of the PR and between 90f8ff4 and e3b9179.

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

Included review availability: Your plan provides up to 10 included reviews per hour; 8 remain after this review.


Walkthrough

The in compound variant now rejects relative arbitrary child variants before selector processing. Regression tests cover in-[>img], in-[+img], and in-[~img], which produce no CSS output. The changelog documents the fix.

Merge Risk: ⚪ Minimal · up to e3b91

The change prevents invalid relative selectors from generating unusable CSS and adds regression coverage for the affected cases; no actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the fix for invalid CSS generated by in-* variants with relative arbitrary selectors.
Description check ✅ Passed The description directly explains the in-* bug, the guard added, the regression tests, and the test results.
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.

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.

@greptile-apps

greptile-apps Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

The PR appears safe to merge with no actionable defects identified.

The guard precisely rejects selector forms that remain relative and therefore invalid inside the :where(...) wrapper, while leaving supported non-relative arbitrary selectors unchanged.

Reviews (1): Last reviewed commit: "Add PR link to changelog entry" | Re-trigger Greptile

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.

1 participant