Every system, rule, and principle a product designer needs, with interactive tools for spacing, contrast, motion, dark mode, and more.
All spacing, sizing, and layout values derive from multiples of 8. Drag the slider to feel the difference between values, not just read them.
| Token | px | rem | Common use |
|---|
Most screens use pixel densities that divide evenly into 8. It maps cleanly to 4, 2, and 1 for micro-adjustments without breaking rhythm.
Use 4px only for micro gaps: icon-label spacing, badge padding, input border offsets. Never for layout or component spacing.
Set 1rem = 16px on :root. Use rem for spacing so browser font-size preferences scale your layout proportionally.
A modular scale generates all type sizes from one base and one ratio. Adjust both below and watch the hierarchy change live.
Body: 1.5 to 1.75. Headings: 1.1 to 1.25. Captions: 1.4. Never go below 1.2 on running text. Tight line-height causes readers to re-read lines.
Large headings: -0.02em to -0.04em. Body: 0. All-caps labels: +0.06em to +0.12em. Negative tracking on small text destroys legibility.
Optimal reading width: 60 to 75 characters. Use max-width: 65ch on paragraphs. Shorter than 40 chars feels choppy; longer than 90 chars strains the eye.
300: large display only. 400: body. 500: UI labels. 600: subheadings. 700: headings. Avoid 800/900 in body. Never use more than 3 weights per interface.
A grid is not just columns. Choose a breakpoint and a pattern below to see how real layouts use the grid.
Desktop: 24 to 32px. Tablet: 16 to 24px. Mobile: 16px. Gutters create breathing room between columns. They are not the same as outer margins.
Set a max-width on your content container, not a fixed width. 1100 to 1280px suits most sites. Use margin: 0 auto to center it.
Modern CSS lets components respond to their parent container size, not just the viewport. This enables truly reusable design system components.
"Design is not just what it looks like and feels like. Design is how it works."Steve Jobs
Every component is made of named parts, each controlled by a design token. Naming the parts lets teams discuss, document, and override them precisely.
[component]-[part]-[property]-[state]. Example: button-bg-primary-hover. Semantic names decouple the design from a specific color value, enabling full re-theming.
Without named parts, design handoff becomes "make it a bit darker" or "add some padding." Named parts + tokens means "set button-bg-primary to brand-500" -- unambiguous and systematic.
Every interactive component must handle all states. Click each component below to cycle through its states and see how they should look and behave.
Never show a blank screen. Provide an illustration, explanation of what belongs here, and a primary CTA to add content. Empty states are conversion opportunities.
Show a skeleton screen for content taking more than 300ms. Skeletons should mirror the final layout shape. Use spinners only for indeterminate full-page loads.
Error messages must explain what went wrong and what the user can do next. "An error occurred" is not a valid message. Be specific. Be human.
Three tools create visual separation: shadows, borders, and background color changes. Each carries a different connotation. Use them deliberately, not interchangeably.
Implies depth and interactivity. Best for cards, buttons, and overlays.
Structural, flat, no depth implied. Good for forms, tables, and data-dense layouts.
Softest signal. Groups content zones without implying hierarchy. Best for layout sections.
Drop shadows are nearly invisible on dark backgrounds. Use surface tint instead: each elevation level is a slightly lighter background. This is how Material You handles dark mode depth.
Cards in the same interface should all use the same separation method. Mixing shadows and borders for the same component type signals inconsistency and breaks the visual language.
Border radius is not decoration. It communicates brand personality on a spectrum from approachable to authoritative. Your radius system should be intentional and consistent.
Used by financial institutions, enterprise software, and government services. Communicates precision, rigidity, and formality. Bloomberg, Reuters, and most bank dashboards.
The default for most B2B products. Approachable but serious. Works across most industries without sending a strong personality signal. GitHub, Notion, Linear.
Consumer apps, social products, and tools targeting creatives. Slack, Figma, and most startup products live in this range. Signals approachability and warmth.
Motion communicates relationships, feedback, and hierarchy. Watch each ball to see how different easing curves feel -- linear is robotic; spring feels alive.
ease-out: Elements entering the screen. ease-in: Elements leaving. ease-in-out: Moving between two positions. Spring: Micro-interactions and delight moments. Linear: Progress indicators only.
Always implement prefers-reduced-motion: reduce. Replace animations with instant state changes or simple opacity fades. Vestibular disorders affect 35% of adults over 40.
"Good design is obvious. Great design is transparent."Joe Sparano
Color contrast is a legal accessibility requirement in many jurisdictions. Test any pair below against both WCAG 2.2 and the newer APCA standard.
WCAG uses a weighted RGB formula. Green contributes 71.5%, red 21.3%, blue 7.2% -- matching human cone sensitivity. Two luminance values give you the contrast ratio.
UI components and icons need 3:1 against adjacent colors (WCAG 1.4.11). Often missed: input borders, icon fills, focus rings, and chart lines.
WCAG 1.4.1: color cannot be the only visual means of conveying information. Links need underlines. Error states need icons or text. Charts need patterns or labels.
Design tokens are the single source of truth for design decisions. Three tiers decouple raw values from meaning from component usage, enabling theming at scale.
Named by value, not meaning
Named by role, references primitives
Scoped to one component
[category]-[property]-[variant]-[state]. Example: color-action-primary-hover. Avoid names that encode the value: blue-500 is a primitive. color-brand-primary is semantic.
CSS custom properties for web. Swift enums for iOS. Kotlin constants for Android. JSON as the shared source. Style Dictionary transforms one JSON source into all platform formats automatically.
Swap semantic tokens to switch from light to dark mode, or from one brand to another. The component code never changes -- only the token map changes. This is how multi-brand design systems work.
Dark mode is not color inversion. Toggle the switch below to see how tokens remap -- and why each design decision is different from the light version.
On dark backgrounds, drop shadows vanish. Use slightly lighter surface backgrounds to imply elevation: each layer 5 to 8% lighter than the one below.
Fully saturated colors look harsh on dark surfaces. Decrease saturation 10 to 20% and increase lightness slightly for dark-mode accent colors. Avoid neon unless it is your brand.
#000000 causes halation -- text appears to bleed against pitch black. Use #0f172a or #121212 as the base surface. Pure black is reserved for OLED battery-saving modes only.
Never hardcode colors in components. Reference semantic tokens. Then dark mode is just a second token map -- your components never change, only the values behind the tokens change.
Z-index bugs are among the most common and frustrating UI issues. A defined z-index scale and an understanding of stacking contexts prevents them entirely.
A new stacking context is created by transform, opacity < 1, filter, will-change, position + z-index, and isolation: isolate. A child can never escape its parent stacking context, which is why a dropdown inside a transformed container appears below a modal.
Add isolation: isolate to a component wrapper to create a deliberate stacking context without using z-index or position. This contains the component's internal z-index wars without affecting the rest of the document.
"The details are not the details. They make the design."Charles Eames
The brain groups visual elements automatically. Mastering these six principles means controlling perceived relationships without adding any visual noise.
Hierarchy guides the eye through content in order of importance. It is built from size, weight, color, contrast, spacing, and position -- never decoration.
The most powerful hierarchy signal. A 32px bold heading dominates a 14px regular body without any color help. Use a maximum of 3 visual weight levels per screen.
High contrast implies high importance. Use your text color scale: primary (high emphasis), secondary (medium), tertiary (low). Resist adding more than 3 text color roles.
More space around an element implies higher importance. Use generous spacing to elevate primary content, reducing the need for borders or dividers to create structure.
60-30-10 governs color dominance. Density governs how much information fits comfortably. Both are composition tools, not rules to follow blindly.
Dark mode, editorial design, and marketing pages often use 80-15-5 or full inversions. The rule prevents visual chaos in functional interfaces. Creative contexts may deliberately ignore it.
Enterprise tools benefit from density controls (Comfortable / Default / Compact). Gmail, Notion, and Linear all offer this. Persist the preference per user account, not per session.
Microcopy is the smallest copy with the largest impact. Button labels, error messages, empty states, and tooltips are all moments of conversation with your user.
"Your file was deleted" is passive. "File deleted" is active. Active voice is faster to read and sounds more confident. Reserve passive voice for when the agent is unknown or unimportant.
"Done" tells the user nothing. "Message sent to sarah@co.com" confirms exactly what happened. Specific feedback reduces anxiety and builds confidence in the system.
Write at a 7th-grade reading level for general audiences. Avoid jargon and system-internal terms. "Something went wrong" beats "Error 500 Internal Server Error" every time.
These principles underpin every good interface ever designed. When in doubt, return to these before adding anything new.
"Simplicity is not the absence of clutter -- it is the achievement of clarity."Jonathan Ive
Accessibility is not a checklist -- it is a design quality. Inaccessible UI is broken UI for 1.3 billion people globally who have some form of disability.
Every interactive element needs a visible focus ring. WCAG 2.4.11 (Focus Appearance) is new in 2.2. Minimum 2px outline, 3:1 contrast against the adjacent color. Never outline: none without a replacement.
Use native HTML elements first. <button> is better than <div role="button"> because it gets keyboard focus, click events, and semantics for free. ARIA only supplements what native HTML cannot express.
Design for content, not device sizes. Breakpoints should emerge from where the layout breaks, not from a list of current screen widths.
Start with the smallest layout and layer complexity up. Use min-width queries. This prevents CSS bloat from overrides and ensures a baseline that always works.
clamp(min, preferred, max) creates fluid type and spacing that scales with the viewport without any media queries. Combine with vw units for true fluid scaling.
Components can now respond to their parent container size with @container. This enables truly reusable components that adapt to any context, not just the viewport.
Forms are the highest-friction UI pattern. Every unnecessary field costs conversions. Every missing validation message costs trust.
Top-aligned labels outperform side-aligned labels in form completion rate. Floating labels save vertical space but hurt readability. Placeholder text is not a label substitute -- it disappears when typing begins.
Validate on blur (after leaving the field), not on every keystroke. Validate on submit as a final check. Showing errors while the user is still typing causes frustration before they have finished.
When most fields are required, mark optional ones with "(optional)" instead. The asterisk convention is widely misunderstood. If you use asterisks, always show a legend explaining them.
Width should hint at expected content length. A 4-digit PIN field should be narrow. A biography textarea should be wide and multi-line. Full-width inputs for short data are a form anti-pattern.
Feedback tells users whether their action worked, failed, or is in progress. The right pattern depends on urgency, interruption cost, and whether persistence is needed.
4 to 6 seconds visibility. Include an undo option for destructive actions. Pause the timer on hover. Never use a toast for an error that blocks the user from continuing.
Use modals for decisions requiring full attention that cannot be undone. Use inline patterns for everything else. Every unnecessary modal erodes user trust and breaks flow.
Icons are a visual language. Consistency in stroke weight, optical sizing, and style determines whether your icon set feels like a system or an accidental collection.
Tests consistently show icon-only navigation is misunderstood -- except for universally recognized symbols (home, close, search, back). When in doubt, add a label. Icons alone fail new users.
Choose one style (outline, filled, or duotone) and apply it everywhere. Mixing styles within an interface signals a lack of intention and makes the UI feel assembled rather than designed.
An 18px icon still needs a 44x44px touch target. Extend the hit area with padding, or use a transparent click wrapper. Never shrink the touch target to match the visual size of the icon.
At small sizes, simplify the icon: remove fine details, increase stroke weight, round corners more aggressively. Same concept, different geometry. Scaling the same SVG down does not work.
These numbers come up constantly. Memorize them and you will spend less time looking things up and more time designing.