Visual Design Fundamentals
The four pillars of visual design for developers who build web interfaces: typography, color, spacing, and visual hierarchy. This is not a design theory textbook — these are practical rules and CSS patterns you can apply immediately to make your UIs look and feel professional.
Typography
Typography is the single biggest lever for visual quality. Get it right and even a plain layout looks polished. Get it wrong and no amount of color or imagery saves it.
Type Scale
Use a modular type scale for consistent, harmonious font sizes. Pick a base size and a ratio, then derive every other size from it. Common ratios include Major Third (1.250) and Perfect Fourth (1.333).
Define your scale as CSS custom properties so every component draws from the same set of values:
:root {
--text-xs: 0.75rem; /* 12px */
--text-sm: 0.875rem; /* 14px */
--text-base: 1rem; /* 16px */
--text-lg: 1.125rem; /* 18px */
--text-xl: 1.25rem; /* 20px */
--text-2xl: 1.5rem; /* 24px */
--text-3xl: 1.875rem; /* 30px */
--text-4xl: 2.25rem; /* 36px */
}
For fluid sizing that adapts smoothly across viewports, use clamp():
h1 {
/* Minimum 1.875rem, scales with viewport, caps at 2.25rem */
font-size: clamp(1.875rem, 1rem + 2vw, 2.25rem);
}
See Design Tools & Resources for type scale calculators.
Body Text
Use 16px minimum for body text. Browsers default to 16px for a reason — it's the threshold for comfortable reading on screens. Never go below 14px for any readable text.
16px also prevents iOS Safari from auto-zooming on form inputs. If your <input> font size is below 16px, Safari zooms the viewport on focus — a frustrating experience on mobile.
Developers consistently make body text too small. This is the #1 typography mistake. When in doubt, go larger.
Line Height and Line Length
Body text needs room to breathe. Cramped lines are hard to read; overly long lines cause readers to lose their place.
- Body text:
line-height: 1.5to1.75. WCAG 1.4.12 recommends at least 1.5. - Headings:
line-height: 1.1to1.3. Tighter line height works for large text. - Optimal line length: 45–75 characters per line. Use
max-width: 65chon text containers. - Paragraph spacing: WCAG 1.4.12 recommends at least 2× the font size between paragraphs.
.prose {
max-width: 65ch;
line-height: 1.6;
font-size: var(--text-base);
}
.prose h2 {
line-height: 1.2;
margin-top: 2em;
}
Font Pairing
Limit typefaces to two maximum. Use weight and size variations within each typeface for contrast — adding a third font almost always hurts coherence.
- Pair a serif with a sans-serif, or use the same superfamily (e.g., Roboto + Roboto Slab).
- Use a distinctive font for headings, a neutral font for body text.
- Popular free pairings: Inter + Merriweather, Roboto + Roboto Slab, Source Sans 3 + Source Serif 4.
System font stacks are a zero-effort baseline with excellent performance:
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
}
Font Loading
Poor font loading causes invisible text (FOIT) or layout shifts (FOUT). Handle it deliberately:
- Use
font-display: swapto show fallback text immediately while the web font loads. - Preload critical fonts:
<link rel="preload" href="/fonts/Inter.woff2" as="font" type="font/woff2" crossorigin>. - Use WOFF2 format — it has the best compression of any web font format.
- Self-host fonts with Fontsource for privacy and performance instead of loading from Google Fonts CDN.
- Consider system font stacks when maximum performance matters more than brand typography.
Color
Contrast and Readability
Sufficient contrast is non-negotiable. WCAG defines minimum contrast ratios for accessibility:
| Text Type | Minimum Ratio |
|---|---|
| Normal text (under 18pt) | 4.5:1 |
| Large text (≥18pt or ≥14pt bold) | 3:1 |
| UI components and graphics | 3:1 |
| Level AAA (enhanced) | 7:1 / 4.5:1 |
Pure black (#000) on pure white (#FFF) produces a 21:1 ratio — technically compliant but visually harsh. Prefer near-black on near-white for a softer read:
:root {
--color-text: #1a1a1a;
--color-bg: #fafafa;
}
See Accessibility as Design for full WCAG color guidance.
Building a Color Palette
Start minimal: one primary brand color, one secondary or accent color, and a neutral gray scale. Expand only when you have a clear reason.
Apply the 60-30-10 rule: 60% dominant color (backgrounds, large surfaces), 30% secondary (cards, navigation, panels), 10% accent (CTAs, highlights, active states).
:root {
/* Primary */
--color-primary-500: #2563eb;
--color-primary-600: #1d4ed8;
--color-primary-700: #1e40af;
/* Neutral */
--color-gray-50: #f9fafb;
--color-gray-200: #e5e7eb;
--color-gray-500: #6b7280;
--color-gray-800: #1f2937;
--color-gray-900: #111827;
/* Accent */
--color-accent-500: #f59e0b;
}
See Design Tools & Resources for palette generators and contrast checkers.
Semantic Colors
Map colors to meaning so users build consistent mental models across your application:
- Success — green (confirmations, completed states)
- Warning — amber or orange (caution, non-blocking issues)
- Error — red (failures, destructive actions, validation errors)
- Info — blue (neutral informational messages)
Never use color as the only way to convey meaning. About 8% of males have some form of color vision deficiency. Always pair color with text, icons, or patterns. A red border alone is not enough — add an error message and an icon.
See Accessibility as Design for more on color independence.
Color Psychology
Color carries associations that influence how users perceive your interface:
| Color | Association | Typical UI Usage |
|---|---|---|
| Blue | Trust, stability | Primary actions, links |
| Green | Success, growth | Confirmations, positive states |
| Red | Urgency, error | Destructive actions, alerts |
| Yellow/Orange | Warning, attention | Warnings, notifications |
| Gray | Neutral, professional | Body text, borders, UI chrome |
These associations are culturally dependent — the table above reflects Western-centric defaults. Research your audience if you're building for a global user base.
Dark Mode
Dark mode is more than inverting colors. Key differences from light mode:
- Surfaces, not shadows: Use elevated surface colors (lighter grays) to create depth instead of drop shadows.
- Reduce saturation: Saturated colors vibrate against dark backgrounds. Desaturate or use lighter tints.
- Test contrast: Colors that pass WCAG on light backgrounds may fail on dark ones. Re-check every combination.
@media (prefers-color-scheme: dark) {
:root {
--color-text: #e5e7eb;
--color-bg: #111827;
--color-surface: #1f2937;
--color-surface-elevated: #374151;
}
}
Dark mode is increasingly expected, but it adds significant design and engineering overhead. Plan for it from the start if it's a requirement — retrofitting is expensive.
Spacing and Layout
The 4px / 8px Grid
Use multiples of 4px for all spacing, sizing, and layout decisions. This eliminates "should this be 13px or 15px?" debates and creates a natural visual rhythm.
Common scale: 4, 8, 12, 16, 24, 32, 48, 64.
:root {
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 0.75rem; /* 12px */
--space-4: 1rem; /* 16px */
--space-6: 1.5rem; /* 24px */
--space-8: 2rem; /* 32px */
--space-12: 3rem; /* 48px */
--space-16: 4rem; /* 64px */
}
This scale matches Tailwind CSS's default spacing system (p-1 = 4px, p-2 = 8px, etc.), making it a widely understood reference point.
Spacing Scale
A spacing scale is a design token — a named value that the entire team agrees on. Instead of hardcoding padding: 17px in one component and padding: 20px in another, use padding: var(--space-4) consistently.
See Design Systems for how spacing scales fit into a broader design token architecture.
Whitespace
Whitespace is not empty space — it is an active design element that communicates structure and relationships.
- Group related items: Use less space between related elements and more space between unrelated ones. This is the Law of Proximity in action.
- Separate before decorating: Before adding a border or background color to separate elements, try adding whitespace first. It's cleaner and costs nothing.
- Pad interactive elements generously: Generous padding inside buttons and links feels higher quality and makes targets easier to hit (Fitts's Law).
- Don't fear open space: Developers consistently underuse whitespace. When a layout feels cluttered, the fix is usually more spacing — not fewer elements.
Visual Hierarchy
Visual hierarchy guides the user's eye through your interface in the order you intend. Without it, every element competes for attention and nothing stands out.
Scanning Patterns
Users don't read — they scan. Two dominant patterns:
- F-pattern: For text-heavy pages (articles, documentation, search results). Users scan horizontally across the top, then a shorter horizontal scan below, then vertically down the left edge. Place key information along these scan lines.
- Z-pattern: For sparse, visual pages (landing pages, hero sections). Users scan top-left → top-right → diagonal → bottom-left → bottom-right. Place your headline top-left and your CTA bottom-right.
Place the most important content along these natural scan paths. Fighting scanning patterns wastes your strongest content on areas users skip.
Creating Hierarchy
Six tools create visual hierarchy. Use them in combination:
- Size — Larger elements are seen first. Use your type scale to create clear size differences between heading levels.
- Weight — Bold draws attention. Use
font-weightstrategically — if everything is bold, nothing is. - Color and contrast — High-contrast elements pop forward. Your primary CTA should have the highest contrast on the page.
- Position — Top-left (in LTR layouts) gets the most attention. Place the most important content there.
- Spacing — Isolated elements surrounded by whitespace draw attention. Give key content room to breathe.
- Depth — Shadows and elevation suggest importance and interactivity. Material Design's elevation system is a well-documented reference for this technique.
The Squint Test
Blur your eyes or zoom your browser to 25%. If you can still identify the primary action and the content hierarchy, the design works. If everything blurs into the same visual weight, your hierarchy needs work. This is the single fastest design self-review technique.
Further Reading
- Laws of UX — The psychological principles behind these guidelines.
- Design Tools & Resources — Type scale calculators, color palette generators, and contrast checkers.
- Design Systems — Design tokens, spacing scales, and component governance at the system level.
- Tailwind CSS — Tailwind's built-in spacing, color, and type scales as a reference implementation.