Skip to content

fix: handle remaining Tailwind v4 scoped CSS cases#1692

Open
rysinal wants to merge 1 commit into
jd-opensource:masterfrom
rysinal:codex/fix-tailwind4-scoped-css
Open

fix: handle remaining Tailwind v4 scoped CSS cases#1692
rysinal wants to merge 1 commit into
jd-opensource:masterfrom
rysinal:codex/fix-tailwind4-scoped-css

Conversation

@rysinal
Copy link
Copy Markdown

@rysinal rysinal commented May 14, 2026

Background

Tailwind CSS v4 support was tracked in #1550 and the follow-up PR #1628 was released in 1.0.0-rc.30. That PR fixed the @layer parsing path, but there are still two scoped CSS parser cases that make Tailwind v4 output invalid in child apps.

In a real micro-app integration using @micro-zoe/micro-app@1.0.0-rc.30, styles were still missing after upgrading because Tailwind v4 emits CSS that includes:

  • CSS registered custom properties such as @property --tw-* { ... }.
  • Selectors/classes containing commas that are not selector-list separators, especially arbitrary values and modern pseudo-class arguments.

This also matches the currently open #1690 report, where the failing Tailwind class contains an arbitrary gradient value: group-hover:bg-[linear-gradient(180deg,transparent_60%,rgba(0,_0,_0,_.6)_93%)].

Root cause

  1. CSSParser.matchAtRule() does not recognize @property. When scoped CSS parses Tailwind v4 output, the parser falls through to the normal style-rule path and can incorrectly scope @property as if it were a selector. The resulting CSS is invalid, so browser-side style application diverges from direct child-app access.

  2. formatSelector() currently splits selector lists with a regular expression that treats every comma as a selector separator. That works for simple selector lists like .a, .b, but it is not safe for Tailwind v4 / modern CSS output where commas can appear inside:

  • :is(...) / :where(...) / :has(...) arguments.
  • Escaped arbitrary utility names such as .grid-cols-\[minmax\(0\,_1fr\)\].
  • Arbitrary values/functions such as linear-gradient(...) and nested rgba(...).

When those inner commas are split as top-level selector separators, scoped CSS inserts micro-app[name=xxx] into the middle of one logical selector, causing the corresponding Tailwind rule to stop matching.

Changes

  • Add a dedicated @property rule parser and handle it like other self-contained at-rules.
  • Replace the selector-list regex splitter with a small stateful scanner.
    • Tracks bracket depth.
    • Tracks parenthesis depth.
    • Skips escaped characters.
    • Splits only on top-level commas.
  • Keep the existing behavior for simple selector lists and body/root handling.
  • Add regression coverage for:
    • @property --tw-*.
    • Commas inside :is() / :has().
    • Escaped Tailwind arbitrary class selectors containing a comma.

Why this is separate from #1628

#1628 fixed one Tailwind v4 blocker around @layer statement/block parsing and was included in 1.0.0-rc.30. The remaining failures described here are different parser gaps:

  • @property is still not recognized as an at-rule.
  • The selector splitter is still comma-regex based and cannot distinguish top-level selector separators from commas inside modern selector/function syntax.

So users on rc.30 can still see missing styles even though #1550 is closed, especially when Tailwind emits arbitrary utilities or registered custom properties.

Validation

  • npm ci
  • npx jest src/__tests__/source/scoped_css.test.ts --runInBand --setupFiles <temporary Worker mock>
    • The temporary Worker mock is only for the local Node 22 + JSDOM environment; without it the existing WorkerProxy initialization fails before scoped CSS tests run because window.Worker is undefined.
    • Result: 9 passed, 3 skipped.
  • npx eslint src/sandbox/scoped_css.ts
  • npx eslint --no-ignore src/__tests__/source/scoped_css.test.ts
  • git diff --check
  • npm run build

Fixes #1690.
Related to #1550 and #1628.

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.

子应用tailwindcss v4不显示自定义样式

1 participant