Introduction
Developers often need to make design decisions. Understanding fundamental UI/UX principles helps create better user experiences. This guide covers design essentials for developers.
Visual Hierarchy
What Is Visual Hierarchy
The arrangement of elements to show their importance.
Techniques
Size and Scale:
/* Larger = more important */
h1 { font-size: 2.5rem; }
h2 { font-size: 2rem; }
p { font-size: 1rem; }
Weight and Emphasis:
.primary { font-weight: 700; }
.secondary { font-weight: 400; }
.muted { font-weight: 300; color: #666; }
Space:
/* More space = more important */
.hero { margin-bottom: 4rem; }
.section { margin-bottom: 2rem; }
.element { margin-bottom: 1rem; }
Typography
Font Selection
Google Fonts:
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
Font Pairing
Common Combinations:
- Inter + Georgia (modern + classic)
- Roboto + Roboto (clean)
- Open Sans + Merriweather (readable + serif)
Reading Experience
/* Optimal reading */
body {
font-size: 16px;
line-height: 1.6; /* 1.5-1.7 is ideal */
max-width: 65ch; /* 60-75 characters per line */
}
Color Theory
Color Wheel
- Primary: Main brand color
- Secondary: Supporting color
- Tertiary: Accent color
Color Schemes
Complementary:
:root {
--primary: #2563EB;
--secondary: #F59E0B; /* Opposite on color wheel */
}
Analogous:
:root {
--primary: #2563EB;
--secondary: #3B82F6;
--tertiary: #60A5FA;
}
Color Psychology
| Color | Meaning |
|---|---|
| Blue | Trust, calm |
| Red | Urgency, passion |
| Green | Growth, success |
| Yellow | Optimism, caution |
| Purple | Luxury, creativity |
Layout Principles
Grid Systems
.container {
display: grid;
grid-template-columns: repeat(12, 1fr);
gap: 1rem;
}
.col-12 { grid-column: span 12; }
.col-8 { grid-column: span 8; }
.col-6 { grid-column: span 6; }
.col-4 { grid-column: span 4; }
.col-3 { grid-column: span 3; }
Responsive Design
/* Mobile first */
.container {
width: 100%;
padding: 1rem;
}
@media (min-width: 768px) {
.container {
max-width: 720px;
margin: 0 auto;
}
}
@media (min-width: 1024px) {
.container {
max-width: 960px;
}
}
Spacing
:root {
--space-1: 0.25rem; /* 4px */
--space-2: 0.5rem; /* 8px */
--space-3: 1rem; /* 16px */
--space-4: 1.5rem; /* 24px */
--space-6: 3rem; /* 48px */
}
User Experience
Usability Principles
- Consistency: Same patterns across app
- Feedback: Show system status
- Affordance: Indicate possible actions
- Error Prevention: Don’t let users fail
User Research Methods
- Interviews: Understand needs
- Surveys: Gather quantitative data
- Usability testing: Observe users
- Analytics: Track behavior
User Flows
graph TD
A[Landing] --> B[Pricing]
B --> C[Sign Up]
C --> D[Onboarding]
D --> E[Dashboard]
E --> F[Create Project]
Accessibility
WCAG Guidelines
Contrast:
/* Minimum contrast 4.5:1 for normal text */
.text {
color: #333;
background: #fff;
}
Focus States:
:focus-visible {
outline: 2px solid blue;
outline-offset: 2px;
}
Semantic HTML:
<!-- Bad -->
<div onclick="submit()">Submit</div>
<!-- Good -->
<button type="submit">Submit</button>
Screen Reader Support
<!-- Visually hidden but readable -->
<span class="sr-only">Close menu</span>
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
Design Systems
What Is a Design System
Collection of reusable components with clear standards.
Components
/* Button */
.btn {
padding: 0.75rem 1.5rem;
border-radius: 0.5rem;
font-weight: 500;
cursor: pointer;
}
.btn-primary {
background: var(--primary);
color: white;
}
.btn-secondary {
background: transparent;
border: 1px solid var(--primary);
color: var(--primary);
}
Documentation
- Usage guidelines
- Code examples
- Accessibility notes
- Do’s and don’ts
Common Mistakes
Design Errors
- Too many fonts: Limit to 2-3
- Low contrast: Hard to read
- Inconsistent spacing: Feels unprofessional
- No visual feedback: Users confused
- Ignoring mobile: Excludes users
Layout and Spacing Systems
The 8px Grid System
Use multiples of 8px for spacing, padding, and layout dimensions:
:root {
--space-1: 4px; /* Quarter unit */
--space-2: 8px; /* Base unit */
--space-3: 12px; /* 1.5 units */
--space-4: 16px; /* 2 units */
--space-6: 24px; /* 3 units */
--space-8: 32px; /* 4 units */
--space-12: 48px; /* 6 units */
--space-16: 64px; /* 8 units */
}
.card {
padding: var(--space-6);
margin-bottom: var(--space-4);
gap: var(--space-4);
}
Component Spacing Guidelines
| Component | Padding | Margin | Gap |
|---|---|---|---|
| Button | 12px 24px | 8px | — |
| Card | 24px | 16px | 16px |
| Modal | 32px | — | 24px |
| Form field | 12px 16px | 16px | 8px |
| Navigation | 16px 24px | — | 8px |
Design System Foundations
A design system codifies design decisions into reusable components and tokens.
Component Architecture
// Button component with design system tokens
interface ButtonProps {
variant: 'primary' | 'secondary' | 'ghost';
size: 'sm' | 'md' | 'lg';
children: React.ReactNode;
disabled?: boolean;
loading?: boolean;
onClick?: () => void;
}
const Button: React.FC<ButtonProps> = ({
variant = 'primary',
size = 'md',
children,
disabled,
loading,
onClick
}) => {
const baseStyles = 'inline-flex items-center justify-center rounded-lg font-medium transition-all duration-200';
const variants = {
primary: 'bg-primary text-white hover:bg-primary-hover active:bg-primary-active',
secondary: 'bg-surface text-text-primary border border-border hover:bg-gray-50',
ghost: 'text-text-secondary hover:bg-surface active:text-text-primary',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm gap-1.5',
md: 'px-4 py-2 text-base gap-2',
lg: 'px-6 py-3 text-lg gap-2.5',
};
return (
<button
className={`${baseStyles} ${variants[variant]} ${sizes[size]}`}
disabled={disabled || loading}
onClick={onClick}
>
{loading && <Spinner size="sm" />}
{children}
</button>
);
};
Responsive Design Patterns
| Breakpoint | Width | Target | Layout Behavior |
|---|---|---|---|
| Mobile | < 640px | Phones | Single column, stacked |
| Tablet | 640-1024px | Tablets | 2 columns, condensed nav |
| Desktop | 1024-1440px | Laptops | Full layout, sidebar |
| Wide | > 1440px | Large monitors | Max-width container, whitespace |
/* Responsive layout with CSS Grid */
.page-layout {
display: grid;
grid-template-columns: 1fr;
gap: var(--space-6);
max-width: 1200px;
margin: 0 auto;
padding: var(--space-6);
}
@media (min-width: 640px) {
.page-layout {
grid-template-columns: 240px 1fr;
}
}
@media (min-width: 1024px) {
.page-layout {
grid-template-columns: 280px 1fr 300px;
}
}
Loading and Empty States
State Design Pattern
Every component should handle these states:
interface ComponentWithStates {
loading: boolean;
empty: boolean;
error: string | null;
data: DataType | null;
}
function DataComponent({ loading, empty, error, data }: ComponentWithStates) {
if (loading) return <Skeleton variant="card" count={3} />;
if (error) return <ErrorState message={error} onRetry={refetch} />;
if (empty) return <EmptyState icon="search" title="No results found" action="Try adjusting your filters" />;
return <DataView data={data} />;
}
Micro-interactions
Subtle animations improve perceived performance and user delight:
/* Button feedback */
.button {
transition: transform 0.15s ease, box-shadow 0.15s ease;
}
.button:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.1); }
.button:active { transform: translateY(0); }
/* Card entrance animation */
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(20px); }
to { opacity: 1; transform: translateY(0); }
}
.card { animation: fadeInUp 0.3s ease-out; }
.card:nth-child(2) { animation-delay: 0.1s; }
.card:nth-child(3) { animation-delay: 0.2s; }
Forms and Data Entry
Form Design Principles
| Principle | Implementation | Impact |
|---|---|---|
| Clear labels | Place above input fields | 20% faster completion |
| Inline validation | Validate on blur, not on keypress | Reduced errors |
| Smart defaults | Pre-select common options | Faster form completion |
| Progressive disclosure | Show advanced options only when needed | Reduced cognitive load |
| Error messages | Specific, actionable error text | Better error recovery |
<!-- Well-designed form field -->
<label class="form-label" for="email">Email address</label>
<input
id="email"
type="email"
class="form-input"
placeholder="[email protected]"
required
aria-describedby="email-hint"
/>
<p id="email-hint" class="form-hint">We'll never share your email.</p>
<p class="form-error" role="alert">Please enter a valid email address.</p>
Visual Hierarchy Implementation
Typography Scale
:root {
--text-xs: 0.75rem; /* 12px - Captions */
--text-sm: 0.875rem; /* 14px - Body small */
--text-base: 1rem; /* 16px - Body */
--text-lg: 1.125rem; /* 18px - Large body */
--text-xl: 1.25rem; /* 20px - Subheading */
--text-2xl: 1.5rem; /* 24px - Heading */
--text-3xl: 1.875rem; /* 30px - Page title */
--text-4xl: 2.25rem; /* 36px - Hero */
--text-5xl: 3rem; /* 48px - Display */
}
Hierarchy via Weight and Color
h1 { font-size: var(--text-4xl); font-weight: 700; color: var(--color-text-primary); }
h2 { font-size: var(--text-3xl); font-weight: 600; color: var(--color-text-primary); }
h3 { font-size: var(--text-2xl); font-weight: 600; color: var(--color-text-primary); }
p { font-size: var(--text-base); font-weight: 400; color: var(--color-text-secondary); }
.caption { font-size: var(--text-xs); font-weight: 400; color: var(--color-text-tertiary); }
Color Systems
Semantic Color Tokens
{
"color": {
"primary": { "value": "#2563EB", "description": "Primary actions, links" },
"primary-hover": { "value": "#1D4ED8", "description": "Primary hover state" },
"background": { "value": "#FFFFFF", "description": "Page background" },
"surface": { "value": "#F8FAFC", "description": "Card, sidebar background" },
"text-primary": { "value": "#0F172A", "description": "Primary text" },
"text-secondary": { "value": "#475569", "description": "Secondary text" },
"border": { "value": "#E2E8F0", "description": "Default border" },
"success": { "value": "#10B981", "description": "Success states" },
"warning": { "value": "#F59E0B", "description": "Warning states" },
"error": { "value": "#EF4444", "description": "Error states" }
}
}
Color Accessibility
All color combinations must meet WCAG 2.1 AA standards:
function checkContrast(foreground, background) {
// Calculate relative luminance
const getLuminance = (hex) => {
const rgb = hex.match(/[A-Fa-f0-9]{2}/g).map(v => parseInt(v, 16) / 255);
const srgb = rgb.map(c => c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4));
return 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
};
const l1 = getLuminance(foreground);
const l2 = getLuminance(background);
const ratio = (Math.max(l1, l2) + 0.05) / (Math.min(l1, l2) + 0.05);
return {
ratio: ratio.toFixed(2),
passesAA: ratio >= 4.5,
passesAAA: ratio >= 7,
passesLargeAA: ratio >= 3
};
}
User Research for Developers
Research Methods
| Method | Time | Participants | Best For |
|---|---|---|---|
| Usability testing | 2-3 hours | 5-8 users | Identifying UX issues |
| Surveys | 1-2 days | 100+ users | Quantitative validation |
| Analytics review | 1 day | All users | Behavioral data |
| Competitive audit | 1-2 days | — | Market positioning |
| Card sorting | 2-3 hours | 15-20 users | Information architecture |
Rapid User Testing Script
// Quick usability test template
const testScript = {
tasks: [
{ name: "Sign up", steps: ["Find sign up button", "Complete form", "Verify email"] },
{ name: "Find product", steps: ["Search for item", "Filter results", "View details"] },
{ name: "Complete purchase", steps: ["Add to cart", "Checkout", "Enter payment"] }
],
metrics: ["Task completion", "Time on task", "Errors", "Satisfaction (1-5)"],
analysis: "Identify top 3 friction points for each task"
};
Prototyping and Testing
Prototype Fidelity
| Fidelity | Tools | Time | Purpose |
|---|---|---|---|
| Low (wireframes) | Pen & paper, Balsamiq | 30 min - 2 hours | Early concept validation |
| Mid (mockups) | Figma, Sketch | 2-8 hours | Visual design exploration |
| High (interactive) | Figma, Framer, Protopie | 1-3 days | User testing, stakeholder approval |
| Code (live) | Storybook, Next.js | 3-10 days | Production-ready validation |
A/B Testing Design Changes
// A/B test implementation
const abTest = {
variants: {
control: { buttonColor: '#2563EB', buttonText: 'Submit' },
treatment: { buttonColor: '#059669', buttonText: 'Save Changes' }
},
metrics: ['click_rate', 'completion_rate', 'time_to_complete'],
sample_size: 1000,
duration: '7 days',
analysis: 'Chi-squared test for significance (p < 0.05)'
};
Design-to-Code Handoff
Specs for Developers
{
"component": "Button",
"states": ["default", "hover", "active", "disabled", "loading"],
"variants": ["primary", "secondary", "ghost", "danger"],
"sizes": ["sm", "md", "lg"],
"props": {
"label": { "type": "string", "required": true },
"variant": { "type": "enum", "options": ["primary", "secondary", "ghost", "danger"] },
"size": { "type": "enum", "options": ["sm", "md", "lg"] },
"disabled": { "type": "boolean", "default": false },
"loading": { "type": "boolean", "default": false },
"onClick": { "type": "function" }
}
}
Design QA Checklist
Before shipping any UI, verify:
- All interactive elements have hover, focus, active, and disabled states
- Color contrast meets WCAG AA (4.5:1 for text, 3:1 for large text)
- Touch targets are at least 44x44px on mobile
- Forms show inline validation with clear error messages
- Loading states (skeleton/spinner) shown during data fetch
- Empty states guide users with helpful messaging
- Error states offer recovery actions (retry, go back)
- Text doesn’t overflow containers at maximum browser zoom (200%)
- Keyboard navigation follows logical tab order
- Screen readers can navigate all content (aria-labels, roles)
- Dark mode works without visual artifacts
- Reduced motion respects prefers-reduced-motion
Design Maturity Model
| Level | Design Process | Developer Collaboration | Tools | Metrics |
|---|---|---|---|---|
| 1: None | No design | Developers design UI | None | None |
| 2: Basic | Ad hoc mockups | Design screenshots | Figma free | Subjective feedback |
| 3: Defined | Design system | Figma + Storybook | Design tools + tokens | Usability scores |
| 4: Managed | User research | Design review process | Full toolchain | NPS, task success |
| 5: Optimized | Continuous testing | Design-engineering pairing | Automated handoff | Business impact metrics |
2026 Design Trends
| Trend | Impact | Implementation |
|---|---|---|
| AI-driven personalization | Adaptive interfaces | User context, ML models |
| Accessibility-first design | Legal compliance, wider audience | WCAG 2.2, European Accessibility Act |
| Micro-interactions | Improved engagement | CSS animations, Framer Motion |
| Dark mode as default | Reduced eye strain, battery saving | CSS custom properties, prefers-color-scheme |
| Design tokens everywhere | Consistent multi-brand UI | W3C Design Tokens spec |
| Developer-designed tools | Lower design barrier | v0, Claude Artifacts, Figma Dev Mode |
Tools and Resources
Design Tools
| Tool | Best For | Price | Learning Curve |
|---|---|---|---|
| Figma | UI/UX design, prototyping | Free/Paid | Low |
| Penpot | Open-source Figma alternative | Free | Low |
| Framer | Interactive prototypes | Paid | Medium |
| Storybook | Component library | Free | Medium |
| Zeroheight | Design system docs | Paid | Low |
Accessibility Tools
| Tool | Purpose | Integration |
|---|---|---|
| axe DevTools | Automated accessibility testing | Browser extension, CI |
| Lighthouse | Performance + accessibility audit | Chrome DevTools, CI |
| WAVE | Visual accessibility checker | Browser extension |
| Color Contrast Checker | WCAG contrast validation | Web app, Figma plugin |
Performance Metrics for Design
| Metric | Target | How to Measure |
|---|---|---|
| Task completion rate | > 85% | User testing, analytics |
| Time on task | < 2 min for core tasks | Analytics |
| Error rate | < 5% | Form analytics, logging |
| Satisfaction (CSAT) | > 4.0 / 5.0 | Post-task survey |
| Net Promoter Score | > 30 | Quarterly survey |
| System Usability Scale | > 68 | Post-study SUS |
| Accessibility score | > 90 | Lighthouse, axe |
Design is a continuous improvement process. The best developers combine technical skill with design thinking to create products that are both functional and delightful.
Conclusion
Design is a skill developers can learn and apply systematically. The key principles are:
- Visual hierarchy — Use typography, color, and spacing to guide attention
- Consistency — Establish design tokens and reusable components
- Accessibility — Meet WCAG standards, test with real users
- User research — Validate designs before building
- Iterate — Measure, learn, improve
Good design improves user satisfaction, reduces support burden, and increases conversion. The investment in learning design fundamentals pays dividends across every project you build.
Implementation Priority Matrix
| Knowledge Area | Effort to Learn | Impact | Priority |
|---|---|---|---|
| Spacing and layout | Low | High | 1 |
| Typography | Low | High | 2 |
| Color | Medium | High | 3 |
| Accessibility | Medium | High | 4 |
| User research | High | High | 5 |
| Design tools | Medium | Medium | 6 |
| Prototyping | High | Medium | 7 |
Start with spacing and typography — they provide the highest improvement per effort invested.
Quick Reference: UI Design Principles
- Less is more — remove elements that don’t serve a purpose
- Consistency reduces learning cost — use familiar patterns
- Visual hierarchy guides attention — use size, color, position
- Feedback confirms actions — every interaction should respond
- Accessibility is not optional — design for all users from day one
Resources
- Material Design 3
- Refactoring UI
- Design Principles FTW
- A11y Project
- WCAG 2.2 Guidelines
- Every Layout
Comments