paletteEngineering
Styling & Tailwind
Utility-first styling, design tokens, composing variants, responsive and dark mode, keeping class soup readable.
1 item
Links1
01NotesNote
Why utility-first works
Tailwind keeps styles co-located with markup, eliminates the naming problem (no more .card__header--active), and ships only the classes you actually use. No context-switching to a separate CSS file, no dead styles piling up. The trade-off is verbose className strings — manage that with extraction, not by abandoning the approach.
Design tokens are the foundation
- Define your palette, spacing, fonts, and radii in the theme config (or CSS variables in v4). Then use
bg-brand,text-muted,rounded-card— semantic tokens, not raw hex values scattered through components. - This is what makes a redesign a config change instead of a find-and-replace. Tie tokens to your actual brand (e.g. the
#0066ccblue), not Tailwind's defaults.
Taming long class lists
- Extract a component, not a CSS class. Repeated button markup → a
<Button>component with variants. This is the React-native answer to "I'm repeating classes." - For variant logic, use
cva(class-variance-authority) ortailwind-mergeto compose conditional classes cleanly and resolve conflicts (so a laterpx-4correctly overrides an earlierpx-2). - Keep conditional classes readable with a
clsx/cnhelper rather than template-string spaghetti.
Responsive & dark mode
- Mobile-first: unprefixed = base, then
sm:md:lg:layer up. Design the small screen first, enhance upward. - Dark mode via the
dark:variant. Drive it off aclassstrategy so you can toggle it with a theme switch, and define both light and dark token values once.
When to drop to raw CSS
- Complex keyframe animations, very specific one-off layouts, or
@supportsqueries can be cleaner in a small CSS file or a<style>. Tailwind isn't dogma — use plain CSS where it's genuinely clearer.
Consistency beats cleverness
- Pick spacing/size scales and stick to them. The value of a design system is the constraint. Use a UI primitive layer (Radix + Tailwind, or shadcn/ui) for accessible, consistent building blocks instead of hand-rolling every dropdown and dialog.