Shadow & Border-Radius System
Elevation scales and radius tokens that convey depth and hierarchy consistently.
Design TokensBeginner
Why
Random shadows (10 different blurs) and radii (4px, 6px, 8px, 12px mixed) make a UI look unpolished. A small elevation scale and 3 radii convey depth and grouping without arbitrary choices.
Tokens Studio (formerly Figma Tokens) has 500k+ installs, and the W3C Design Tokens Format Module is nearing candidate recommendation. Tokens enable dark mode, multi-brand theming, and platform parity from a single source.
When
Define shadows and radii alongside the color scale. If you have 5+ shadow definitions, consolidate into an elevation scale of 4-5 levels.
How
1. Elevation scale — none, sm (1px), md (4px), lg (8px), xl (16px) — maps to z-depth meaning
2. Shadow recipe — y-offset = blur/2, opacity 0.05-0.15, single light direction (top-left)
3. Radius scale — sm=4, md=8, lg=12, full=9999 (pill); 3-4 values max
4. Pair by surface — card=md radius+sm shadow, modal=lg radius+lg shadow, dropdown=sm radius+md shadow
5. Dark mode — shadows are invisible on dark; use 1px border + lighter surface instead
6. Tokens — --shadow-{none|sm|md|lg|xl}, --radius-{sm|md|lg|full}
7. Enforce — stylelint bans raw box-shadow and border-radius values
Example
/* shadow-radius-tokens.css */
:root {
--radius-sm: 4px;
--radius-md: 8px;
--radius-lg: 12px;
--radius-full: 9999px;
--shadow-none: none;
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
--shadow-md: 0 4px 8px 0 rgb(0 0 0 / 0.08);
--shadow-lg: 0 8px 16px 0 rgb(0 0 0 / 0.10);
--shadow-xl: 0 16px 32px 0 rgb(0 0 0 / 0.12);
}
/* Surface pairing — depth conveyed by radius + shadow together */
.card { border-radius: var(--radius-md); box-shadow: var(--shadow-sm); }
.modal { border-radius: var(--radius-lg); box-shadow: var(--shadow-lg); }
.dropdown{ border-radius: var(--radius-sm); box-shadow: var(--shadow-md); }
.pill { border-radius: var(--radius-full); }
/* Dark mode — shadows invisible, use border + surface elevation */
:root[data-theme="dark"] .card {
box-shadow: none;
border: 1px solid var(--color-border-subtle);
background: var(--color-surface-raised);
}
Common Problems
- ⚠Multiple light directions — one shadow goes down-right, another up-left, looks broken
- ⚠Shadows in dark mode — invisible, elevation lost, modal looks flat against the page
- ⚠Radius inconsistency — card 8px, its header 6px, the image 12px, looks stitched together
Best Practices
- ✓One light direction, one shadow recipe — vary only y-offset and blur across the scale
- ✓In dark mode, replace shadows with borders + surface color elevation
- ✓Match radius to the parent — inner elements use the same or smaller radius, never larger