patterncsstailwindTip
Restyle a whole Tailwind 4 app to a new visual reference without mixing two styles per screen
Viewed 0 times
Tailwind CSS 4+, Next.js 16
@utility@themerestyletoken aliasfont-feature-settingscontrast test
browsernodejs
Problem
When an existing Tailwind 4 app must be restyled to match a reference UI (colors, font, radii, component shapes) screen by screen across many PRs, intermediate states mix the old and new palettes on the same screen, and copy-pasted class strings (buttons, inputs) drift. Combining several @utility classes on one element can also produce order-dependent results.
Solution
1) First PR: write the new @theme with new token names, and temporarily redefine the OLD token names with the NEW values (aliases). Every screen switches palette, font and radii at once while keeping its layout. 2) Declare components once as @utility classes in globals.css (button variants, sizes, input, checkbox, tabs, table, menu, alert), using nested selectors for states (&:hover, &:disabled, &[aria-current="page"], &[aria-pressed="true"]). Split each component into a variant class (colors/border/weight) and a size class (height/padding/font-size) that never set the same property, so class order never matters. They work on button, Link and summary alike, without JS. 3) Each later PR reworks one whole group of screens (never half a screen). 4) Last PR removes the old alias names and a test scans src/ to prove none remain. 5) Add a unit test that parses the token values from globals.css and checks WCAG contrast of every text/background pair you use (4.5) and control borders (3).
Why
Aliasing gives a single coherent palette immediately, so the remaining differences are layout only; splitting variant and size utilities avoids Tailwind's utility sorting deciding which background or padding wins.
Gotchas
- --default-font-feature-settings in @theme applies an OpenType feature (e.g. "ss01") to html; Tailwind's preflight makes inputs and buttons inherit it, but reset it on title classes using another font
- next/font/google may serve subset files: verify a stylistic set survives (canvas.measureText width with and without the feature differs); otherwise fall back to next/font/local with the OFL file from the google/fonts repo
- Overriding --text-sm--line-height or --breakpoint-md changes every existing text-sm / md: usage at once: intended, but check pages at 375 px for horizontal scroll
- After rewriting globals.css, the Next 16 Turbopack dev cache may keep the old CSS: stop dev and move .next/dev away
Context
Planning a multi-PR visual redesign of an existing Next.js + Tailwind 4 app
Revisions (0)
No revisions yet.