Skip to content

fix(tailwind): tw-* variables in non inlined rules#3542

Merged
gabrielmfern merged 10 commits into
canaryfrom
feature/dev-638-tailwind-print-styles-break-gmail-media-query
May 26, 2026
Merged

fix(tailwind): tw-* variables in non inlined rules#3542
gabrielmfern merged 10 commits into
canaryfrom
feature/dev-638-tailwind-print-styles-break-gmail-media-query

Conversation

@gabrielmfern
Copy link
Copy Markdown
Member

@gabrielmfern gabrielmfern commented May 26, 2026

Summary by cubic

Fix Tailwind v4 print utilities breaking Gmail by stripping empty-fallback var(--tw-*,) values and removing --tw-* declarations from non‑inlined rules. Restores responsive media queries by resolving variables defined/used in the same nested @media block without leaking to siblings; addresses Linear DEV-638.

  • Bug Fixes
    • Add strip-empty-tailwind-vars; use in make-inline-styles-for and sanitize-non-inlinable-rules.
    • Strip empty var(--tw-*,) in values (including inside print media queries).
    • Remove resolved --tw-* declarations in non-inlinable rules.
    • Resolve vars when use/definition share the same nested at‑rule; prevent cross‑leak to sibling at‑rules; add tests for print:invert and print:border-solid.

Written for commit b61dae5. Summary will update on new commits. Review in cubic

Signed-off-by: gabriel miranda <gabriel@resend.com>
Signed-off-by: gabriel miranda <gabriel@resend.com>
@gabrielmfern gabrielmfern self-assigned this May 26, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 26, 2026

🦋 Changeset detected

Latest commit: b61dae5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
react-email Minor
@react-email/editor Patch
@react-email/ui Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
react-email Ready Ready Preview, Comment May 26, 2026 5:37pm
react-email-demo Ready Ready Preview, Comment May 26, 2026 5:37pm

Request Review

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 26, 2026

Open in StackBlitz

npm i https://pkg.pr.new/react-email@3542

commit: b61dae5

Signed-off-by: gabriel miranda <gabriel@resend.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 1 file (changes from recent commits).

Auto-approved: This change extracts an existing utility to strip empty-fallback --tw-* var() tokens and applies it to non-inlined rules, fixing a Gmail rendering issue without altering any business logic or infrastructure.

Re-trigger cubic

Signed-off-by: gabriel miranda <gabriel@resend.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

cubic analysis

4 issues found across 4 files

Confidence score: 2/5

  • There is a high-confidence, user-visible regression risk (8/10 severity, 9/10 confidence): logic in packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts can remove needed Tailwind vars (for example --tw-invert), causing print:invert to degrade to filter: !important and lose print behavior.
  • packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts appears to only strip var(--tw-...) usages, while non-inlined print rules can still emit --tw-* declarations that Gmail rejects, so email-client compatibility remains at risk.
  • packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.spec.ts snapshots still expect --tw-* variables in @media print, which conflicts with the DEV-638 requirement and suggests the current behavior is not yet aligned with the intended Gmail-safe output.
  • Pay close attention to packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts, packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.ts, and packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.spec.ts - print variant filter/border output still appears to rely on Tailwind variables and can break Gmail-safe rendering.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.spec.ts">

<violation number="1" location="packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.spec.ts:49">
P1: The new snapshot expectation still includes `--tw-*` variables in `@media print`, which contradicts the DEV-638 requirement to emit print styles without Tailwind variables for email-safe output.

According to linked Linear issue DEV-638, this should be validated as variable-free output.</violation>
</file>

<file name="packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts">

<violation number="1" location="packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts:22">
P1: According to linked Linear issue DEV-638, this only strips `var(--tw-...)` usages, so non-inlined rules like `print:border-solid` still emit `--tw-*` declarations that Gmail rejects.</violation>

<violation number="2" location="packages/react-email/src/components/tailwind/utils/css/strip-empty-tailwind-vars.ts:67">
P1: According to linked Linear issue DEV-638, removing every empty-fallback `var(--tw-...)` here also deletes defined vars like `--tw-invert`, so `print:invert` becomes `filter: !important` and loses its print effect.</violation>
</file>

<file name="packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.ts">

<violation number="1" location="packages/react-email/src/components/tailwind/utils/css/sanitize-non-inlinable-rules.ts:36">
P1: According to linked Linear issue DEV-638, this still misses the required Gmail-safe output for variant-stacked filter utilities: stripping `var(--tw-*,)` here turns `print:invert` into `filter:!important`, so the print style stops working instead of becoming `filter: invert(100%) !important`.</violation>
</file>

Linked issue analysis

Linked issue: DEV-638: Tailwind print styles break gmail media query

Status Acceptance criteria Notes
Strip empty-fallback --tw-* var() tokens from inline styles (so inline declarations don't contain var(--tw-...,) fragments) make-inline-styles-for.ts is updated to call the new stripEmptyTailwindVars helper, removing empty-fallback Tailwind var() functions before generating inline styles.
Strip empty-fallback --tw-* var() tokens from non-inlined CSS (e.g., @media print) so Gmail media queries are not broken sanitize-non-inlinable-rules.ts now calls stripEmptyTailwindVars for declarations, collapsing empty var() chains in non-inlinable rules/media queries.
Add tests/spec to prevent regressions for print:invert and similar variant-stacking utilities A spec was added that asserts no var(--tw-[...],) patterns remain in the generated stylesheet and includes a snapshot to lock behavior.
Only target Tailwind-generated --tw- variables (do not remove user custom properties) The helper inspects the var() identifier and only collapses var() calls whose variable name starts with --tw-, preserving other custom properties.

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Signed-off-by: gabriel miranda <gabriel@resend.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

0 issues found across 2 files (changes from recent commits).

Requires human review: Auto-approval blocked by 3 unresolved issues from previous reviews.

Re-trigger cubic

Signed-off-by: gabriel miranda <gabriel@resend.com>
Signed-off-by: gabriel miranda <gabriel@resend.com>
Signed-off-by: gabriel miranda <gabriel@resend.com>
Signed-off-by: gabriel miranda <gabriel@resend.com>
Signed-off-by: gabriel miranda <gabriel@resend.com>
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread .changeset/strip-empty-tw-vars-media-queries.md
@gabrielmfern gabrielmfern merged commit ba99365 into canary May 26, 2026
19 of 20 checks passed
@gabrielmfern gabrielmfern deleted the feature/dev-638-tailwind-print-styles-break-gmail-media-query branch May 26, 2026 18:54
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