fix(react-email): convert border radius and max width to px in pixelBasedPreset
Overview
This PR serves as a bug fix candidate for #3845 - currently pixelBasedPreset is documented as the fix for Tailwind's rem units in email clients, but rounded-* and max-w-* still come out in rem.
Technical difficulties
pixelBasedPreset only overrides theme.extend.fontSize and theme.extend.spacing. Every other scale Tailwind defines in rem passes through unchanged:
| Class | Before | After |
|---|---|---|
rounded, rounded-sm | 0.25rem | 4px |
rounded-md | 0.375rem | 6px |
rounded-lg | 0.5rem | 8px |
max-w-md | 28rem | 448px |
max-w-7xl | 80rem | 1280px |
Considered and rejected:
- Documenting it only (telling users to extend
theme.borderRadiusthemselves). This works, but the preset's name and docs promise pixels, and each user has to rediscover the gap. - Post-processing
remtopxfor every declaration. That would also change values users set deliberately, andemandcalc()cases are not a plain multiply by 16. A scale-by-scale preset keeps the change explicit and opt-out-able, since a user's ownthemestill overrides it.
Each value is what the rem resolves to at a 16px root, matching how the existing spacing and fontSize scales were done.
Changes
tailwind.tsx:pixelBasedPresetgains aborderRadiusscale (DEFAULT,xsto4xl) and amaxWidthscale (3xsto7xl).tailwind.spec.tsx: regression tests for the converted classes, and one that checks no class in either scale still emitsrem.- A
patchchangeset forreact-email.
Side effect worth a look: maxWidth is Tailwind's container scale, so w-md, min-w-md and the other container-sized widths also change from rem to px.
Not addressed: max-w-screen-* (breakpoints, 48rem) and tracking-* (em) still emit rem/em. Outlook on Windows ignores border-radius whatever the unit, so this does not give it rounded corners. I also noticed blur-sm rendering as filter:blur(var(--blur-sm)) with an unresolved variable; that looks like a separate bug.
Testing
- With the fix removed, the 8 new tests fail; with it, they pass. The whole Tailwind suite passes (151 tests), and
tsc --noEmitandbiome checkare clean inpackages/react-email. - Not run: the other packages that import
pixelBasedPreset(for examplepackages/ui), and real email clients.
Demo and evidence
A runnable before/after demo lives on a separate branch so it stays out of this PR:
aporter/2611-rem-from-pixelbasedpreset-demo.
Its README walks through it: cd packages/react-email && npx tsx demo/ab.tsx renders the same email with and without the new scales and prints the rem values found in each, all to local HTML for review. The branch also holds captured evidence (evidence-02.txt to evidence-07.txt: the published-package baseline, per-class output, the scan of Tailwind's rem scales, and the mutation check for the tests).
Summary by cubic
Converts the pixelBasedPreset's border radius and max width scales to pixels, so rounded-* and max-w-* classes no longer emit rem. Previously the preset only overrode fontSize and spacing, leaving these scales in rem values that don't render reliably in email clients.
Side effects
- Because
maxWidthis Tailwind's container scale, container-sizedw-*andmin-w-*classes also switch fromremto pixels. max-w-screen-*andtracking-*still emitrem/em.- Adds regression tests, updates affected snapshots in
react-emailandui, and a patch changeset.