diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fec361f5959..d7789002a9cd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Canonicalization: don't merge utilities that reference different theme variables set to CSS-wide keywords like `unset` ([#20417](https://github.com/tailwindlabs/tailwindcss/pull/20417)) - Don't generate utilities when a modifier is used that would otherwise be silently ignored (e.g. `rounded-sm/[5]`, `shadow-sm/foo`, `stroke-2/50`) ([#20419](https://github.com/tailwindlabs/tailwindcss/pull/20419)) - Only normalize top-level `and`, `or`, and `not` keywords in `supports-[…]` variants (e.g. `selector(a: not (.foo))` → `selector(a:not(.foo))`) ([#20420](https://github.com/tailwindlabs/tailwindcss/pull/20420)) +- Don't generate invalid CSS for `in-*` variants using a relative arbitrary selector (e.g. `in-[>img]`), matching existing behavior for `not-*`, `group-*`, and `peer-*` ([#20424](https://github.com/tailwindlabs/tailwindcss/pull/20424)) ## [4.3.3] - 2026-07-16 diff --git a/packages/tailwindcss/src/variants.test.ts b/packages/tailwindcss/src/variants.test.ts index 454f4c1bf198..8745b5cea19b 100644 --- a/packages/tailwindcss/src/variants.test.ts +++ b/packages/tailwindcss/src/variants.test.ts @@ -2000,6 +2000,10 @@ test('in', async () => { " `) expect(await run(['in-p:flex', 'in-foo-bar:flex'])).toEqual('') + + // `in-*` is built using `:where(…) &`, which — unlike `:has(…)` — does not + // accept relative selectors, so these must not generate any output. + expect(await run(['in-[>img]:flex', 'in-[+img]:flex', 'in-[~img]:flex'])).toEqual('') }) test('has', async () => { diff --git a/packages/tailwindcss/src/variants.ts b/packages/tailwindcss/src/variants.ts index c13c3ae12e39..ab3681846dcd 100644 --- a/packages/tailwindcss/src/variants.ts +++ b/packages/tailwindcss/src/variants.ts @@ -782,6 +782,8 @@ export function createVariants(theme: Theme): Variants { staticVariant('inert', ['&:is([inert], [inert] *)']) variants.compound('in', Compounds.StyleRules, (ruleNode, variant) => { + if (variant.variant.kind === 'arbitrary' && variant.variant.relative) return null + if (variant.modifier) return null let didApply = false