UI Design Fundamentals
The definitive guide for building production-grade web interfaces. Covers the full stack of design decisions from layout to motion.
WHEN To Use
- Designing new UI components or pages
- Building landing pages, dashboards, or applications
- Reviewing code for design quality
- Creating distinctive interfaces that avoid generic aesthetics
- Implementing accessibility requirements
KEYWORDS
ui design, web design, layout, typography, color palette, spacing, visual hierarchy, responsive design, accessibility, motion design, component design, design tokens, frontend, css, tailwind
Installation
OpenClaw / Moltbot / Clawbot
bash
npx clawhub@latest install ui-design
Design Philosophy
The 80/20 of Design Quality
| Factor | Impact | Time Investment |
|---|
| Typography | 40% | Choose 1-2 fonts well |
| Spacing | 25% | Use consistent scale |
| Color | 20% | Limit palette, ensure contrast |
| Everything else | 15% | Shadows, borders, motion |
Focus on typography and spacing first. They're 65% of perceived quality.
Commit to a Direction
Mediocrity is forgettable. Pick an extreme:
| Direction | Characteristics | Use When |
|---|
| Brutally Minimal | Stark, essential, nothing extra | Developer tools, productivity |
| Luxury/Refined | Premium, subtle elegance | High-end products, fashion |
| Playful | Fun, bright, approachable | Consumer apps, games |
| Editorial | Type-forward, grid-based | Content sites, magazines |
| Industrial | Function-forward, robust | B2B, enterprise |
Layout
Grid vs Flexbox Decision
| Layout Need | Tool | Why |
|---|
| Page-level structure | CSS Grid () | Named regions, explicit control |
| Navigation bars | Flexbox | Single-axis, spacing |
| Card grids | Grid (/) | Responsive without media queries |
| Centering | Grid () | Shortest, most reliable |
| Sidebar + content | Grid () | Fixed + fluid |
| Stacking/overlaps | Grid + | No needed |
Container Strategy
css
/* Standard content width */
.container {
width: 100%;
max-width: 1280px;
margin-inline: auto;
padding-inline: clamp(1rem, 5vw, 3rem);
}
/* Full-bleed with contained content */
.full-bleed {
width: 100vw;
margin-left: calc(50% - 50vw);
}
Common Layout Mistakes
| Mistake | Problem | Fix |
|---|
| Mixing container widths | Inconsistent alignment | Use single value |
| Content behind fixed navbar | Hidden content | Add |
| No mobile padding | Edge-to-edge text | Add minimum |
| Centered everything | Weak hierarchy | Left-align body text |
Typography
Typography carries 90% of a design's personality.
Font Pairing by Context
| Context | Display Font | Body Font | Example |
|---|
| Editorial | High-contrast serif | Neutral humanist | Playfair + Source Sans |
| SaaS | Geometric sans | Matching sans | DM Sans + DM Mono |
| Luxury | Thin modern serif | Elegant sans | Cormorant + Jost |
| Developer | Monospace display | Monospace body | JetBrains Mono + IBM Plex |
| Playful | Rounded/quirky | Clean readable | Nunito + Outfit |
Type Scale (1.25 ratio)
css
--text-xs: 0.64rem; /* 10px - captions */
--text-sm: 0.8rem; /* 13px - secondary */
--text-base: 1rem; /* 16px - body */
--text-lg: 1.25rem; /* 20px - lead */
--text-xl: 1.563rem; /* 25px - h4 */
--text-2xl: 1.953rem; /* 31px - h3 */
--text-3xl: 2.441rem; /* 39px - h2 */
--text-4xl: 3.052rem; /* 49px - h1 */
Typography Rules
| Rule | Value | Why |
|---|
| Minimum body size | 16px | Below is hard to read |
| Body line-height | 1.5-1.75 | Improves readability |
| Heading line-height | 1.1-1.2 | Tighter for large text |
| Line length | 60-75 characters | Optimal reading |
| Paragraph spacing | 1.5em | Clear separation |
Typography Mistakes
| Mistake | Problem | Fix |
|---|
| System fonts only | Generic look | Use Google Fonts or variable fonts |
| Too many fonts | Visual chaos | Max 2 families |
| Weak weight contrast | Poor hierarchy | Bold headings (600+), regular body |
| Long lines | Hard to read | Add (65ch) |
Color
Building a Palette
Every palette needs five functional roles:
| Role | Purpose | Usage |
|---|
| Primary | Brand identity | Buttons, links, active states |
| Neutral | Text, backgrounds | Body text, cards, dividers |
| Accent | Secondary actions | Tags, badges, highlights |
| Semantic | Feedback | Success/warning/error states |
| Surface | Layered backgrounds | Cards, modals, overlays |
Surface Layering (Dark Mode)
Create depth through lightness, not shadows:
css
:root {
--surface-0: hsl(220 15% 8%); /* page background */
--surface-1: hsl(220 15% 12%); /* card */
--surface-2: hsl(220 15% 16%); /* raised element */
--surface-3: hsl(220 15% 20%); /* popover/modal */
}
Contrast Requirements (WCAG)
| Text Size | Minimum Ratio | Enhanced (AAA) |
|---|
| Normal text (<18px) | 4.5:1 | 7:1 |
| Large text (≥18px bold, ≥24px) | 3:1 | 4.5:1 |
| UI components | 3:1 | — |
Color Mistakes
| Mistake | Problem | Fix |
|---|
| Purple gradient on white | "AI aesthetic" cliché | Use intentional brand colors |
| Low contrast text | Accessibility fail | Test with contrast checker |
| Color-only indicators | Colorblind users excluded | Add icons/text |
| Too many colors | Visual noise | 3-5 colors maximum |
| Light gray text on white | Unreadable | minimum |
Spacing
8px Base Unit Scale
css
--space-1: 0.25rem; /* 4px - tight gaps */
--space-2: 0.5rem; /* 8px - input padding */
--space-3: 0.75rem; /* 12px - button padding */
--space-4: 1rem; /* 16px - default spacing */
--space-6: 1.5rem; /* 24px - section padding */
--space-8: 2rem; /* 32px - section gaps */
--space-12: 3rem; /* 48px - major breaks */
--space-16: 4rem; /* 64px - page rhythm */
Spacing Rules
| Rule | Implementation |
|---|
| Use not margins | display: flex; gap: var(--space-4)
|
| Consistent padding | Same values on all cards/sections |
| More space between groups | Less space within groups (Gestalt) |
| No arbitrary values | Only use scale tokens |
Spacing Mistakes
| Mistake | Problem | Fix |
|---|
| Arbitrary pixel values | Inconsistent rhythm | Use spacing scale only |
| Margin on children | Margin collapse bugs | Use on parent |
| Equal spacing everywhere | No visual grouping | More between, less within |
| Tight mobile padding | Cramped feeling | Minimum on mobile |
Visual Hierarchy
Guide the eye through deliberate contrast.
Hierarchy Techniques
| Technique | How | Impact |
|---|
| Size | Hero 3-4x body | Immediate focal point |
| Weight | Bold headings, regular body | Scannability |
| Color | Primary vs muted | Information layers |
| Space | Isolation creates emphasis | Draws attention |
| Position | Top-left anchors reading | Natural flow |
Card Hierarchy Pattern
Eyebrow ← xs, uppercase, muted color
Title ← xl, semibold, primary color
Body ← base, secondary color, 1.6 line-height
Action ← spaced apart, mt-4 minimum
Responsive Design
Breakpoint Strategy
| Breakpoint | Target | Key Changes |
|---|
| < 640px | Mobile | Single column, stacked nav, 44px touch targets |
| 640-1024px | Tablet | Two columns, collapsible sidebars |
| 1024-1440px | Desktop | Full layout, hover enabled |
| > 1440px | Wide | Max-width container, prevent ultra-wide lines |
Fluid Techniques
css
/* Fluid typography */
h1 { font-size: clamp(2rem, 1.5rem + 2.5vw, 3.5rem); }
/* Fluid spacing */
section { padding-block: clamp(2rem, 1rem + 4vw, 6rem); }
/* Intrinsic grid */
.grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
gap: var(--space-6);
}
Responsive Mistakes
| Mistake | Problem | Fix |
|---|
| No viewport meta | Broken mobile | Add |
| Fixed widths | Overflow on mobile | Use and |
| Tiny touch targets | Frustrating taps | Minimum 44x44px |
| Hidden horizontal scroll | Broken layout | Test at 375px width |
Accessibility
Accessibility is not optional.
Critical Requirements
| Requirement | Implementation | Standard |
|---|
| Color contrast | 4.5:1 normal, 3:1 large | WCAG 2.1 AA |
| Keyboard navigation | Tab order matches visual | WCAG 2.1.1 |
| Focus indicators | Visible ring | WCAG 2.4.7 |
| Semantic HTML | , , | WCAG 1.3.1 |
| Alt text | Descriptive for images | WCAG 1.1.1 |
| Motion safety | | WCAG 2.3.3 |
| Touch targets | 44×44px minimum | WCAG 2.5.8 |
Focus Styles
css
:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
/* Remove default only if custom exists */
:focus:not(:focus-visible) {
outline: none;
}
Motion Safety
css
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
transition-duration: 0.01ms !important;
}
}
Motion & Animation
Use motion to communicate, not decorate.
Timing Guidelines
| Interaction | Duration | Easing |
|---|
| Button hover | 150ms | ease-out |
| Modal open | 250ms | ease-out |
| Modal close | 200ms | ease-in |
| Page transition | 300ms | ease-in-out |
| Stagger delay | 50-80ms per item | — |
| Micro-feedback | 100ms | ease-out |
Staggered Entrance
css
.item {
opacity: 0;
translate: 0 1rem;
animation: reveal 0.5s ease-out forwards;
}
.item:nth-child(1) { animation-delay: 0ms; }
.item:nth-child(2) { animation-delay: 60ms; }
.item:nth-child(3) { animation-delay: 120ms; }
@keyframes reveal {
to { opacity: 1; translate: 0 0; }
}
Motion Mistakes
| Mistake | Problem | Fix |
|---|
| Animating width/height | Performance hit | Use only |
| > 500ms duration | Feels sluggish | 150-300ms for most |
| Motion everywhere | Overwhelming | Focus on entrances/exits |
| No reduced-motion | Accessibility fail | Always check preference |
Component States
Every interactive element needs clear states.
| State | Visual Treatment |
|---|
| Default | Base styling |
| Hover | Subtle background/shadow shift |
| Active/Pressed | Slight inset, reduced shadow |
| Focus | High-visibility ring |
| Disabled | 50% opacity, cursor |
| Loading | Spinner or skeleton |
Button Example
css
.btn {
transition: all 150ms ease-out;
}
.btn:hover {
background: var(--color-primary-600);
}
.btn:active {
transform: scale(0.98);
}
.btn:focus-visible {
outline: 2px solid var(--color-primary);
outline-offset: 2px;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
Design Tokens Architecture
Structure tokens in three layers:
css
/* Layer 1: Primitives */
--blue-500: oklch(0.55 0.2 250);
--gray-100: oklch(0.95 0.005 250);
--radius-md: 0.5rem;
/* Layer 2: Semantic */
--color-primary: var(--blue-500);
--color-surface: var(--gray-100);
--radius-button: var(--radius-md);
/* Layer 3: Component */
--btn-bg: var(--color-primary);
--btn-radius: var(--radius-button);
--btn-padding: var(--space-2) var(--space-4);
This allows theme switching by remapping Layer 2 only.
Pre-Delivery Checklist
Typography
Color
Spacing
Hierarchy
Responsive
Accessibility
States
Performance
NEVER Do
- NEVER skip contrast checking — Test every text/background combination
- NEVER use color alone — Always pair with icons/text for meaning
- NEVER remove focus outlines — Unless replacing with visible alternative
- NEVER use arbitrary spacing — Stick to the scale
- NEVER animate layout properties — Only and
- NEVER ignore reduced-motion — Always check the preference
- NEVER center everything — Left-align body text
- NEVER use tiny touch targets — 44px minimum
- NEVER use low-contrast text — minimum on white
- NEVER use generic system fonts — Choose intentional typography
Related Skills
- — Searchable design databases with CLI
- — Creative aesthetics, avoiding "AI slop"
- — Applying themes to artifacts
- — Token architecture and theming