UI/UX Design Principles
This skill provides expert guidance on user interface and user experience design, applicable across all frontend frameworks.
When to Apply This Skill
Use these principles when:
-
Designing component layouts and visual hierarchy
-
Creating or improving user flows
-
Making design system decisions
-
Implementing responsive designs
-
Ensuring accessibility compliance
-
Discussing color, typography, or spacing
Core Design Principles
- Visual Hierarchy
Establish Clear Information Architecture
-
Use size, color, and spacing to indicate importance
-
Guide user attention to primary actions
-
Group related elements visually
/* Good: Clear hierarchy */ .card-title { font-size: 1.5rem; font-weight: 600; margin-bottom: 0.5rem; }
.card-description { font-size: 1rem; color: var(--text-secondary); margin-bottom: 1rem; }
.card-metadata { font-size: 0.875rem; color: var(--text-tertiary); }
- Consistency
Design System Tokens
-
Define colors, spacing, typography centrally
-
Use CSS variables or design tokens
-
Maintain consistency across components
:root { /* Spacing scale (4px base) / --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 */
/* Color palette */ --primary: #3b82f6; --primary-hover: #2563eb; --danger: #ef4444; --success: #10b981;
/* Typography */ --font-sans: 'Inter', system-ui, sans-serif; --font-mono: 'Fira Code', monospace; }
- Responsive Design
Mobile-First Approach
-
Design for smallest screen first
-
Progressively enhance for larger screens
-
Use fluid typography and spacing
/* Mobile-first */ .container { padding: var(--space-4); max-width: 100%; }
/* Tablet */ @media (min-width: 768px) { .container { padding: var(--space-6); max-width: 720px; } }
/* Desktop */ @media (min-width: 1024px) { .container { padding: var(--space-8); max-width: 1200px; } }
Fluid Typography
/* Responsive font sizing */ h1 { font-size: clamp(1.75rem, 5vw, 3rem); }
p { font-size: clamp(1rem, 2.5vw, 1.125rem); line-height: 1.6; }
- Accessibility (a11y)
WCAG 2.1 AA Compliance
Color Contrast
-
Text: 4.5:1 minimum contrast ratio
-
Large text (18pt+): 3:1 minimum
-
Interactive elements: Clear focus states
/* Good: Sufficient contrast / .button-primary { background: #2563eb; / Contrast with white text: 8.6:1 */ color: #ffffff; }
/* Focus states for keyboard navigation */ .button:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
Semantic HTML
<!-- Good: Semantic and accessible --> <nav aria-label="Main navigation"> <ul> <li><a href="/">Home</a></li> <li><a href="/about">About</a></li> </ul> </nav>
<main> <article> <h1>Page Title</h1> <section> <h2>Section Title</h2> <p>Content...</p> </section> </article> </main>
<!-- Bad: Divitis and non-semantic --> <div class="navigation"> <div class="nav-item">Home</div> </div>
ARIA Attributes
<!-- Loading state --> <button aria-busy="true" aria-live="polite"> <span aria-hidden="true">⏳</span> Loading... </button>
<!-- Error message --> <input type="email" aria-describedby="email-error" aria-invalid="true" /> <span id="email-error" role="alert"> Please enter a valid email address </span>
- User Feedback
Loading States
// Skeleton screens for content loading function UserCardSkeleton() { return ( <div className="animate-pulse"> <div className="h-12 w-12 bg-gray-300 rounded-full" /> <div className="h-4 bg-gray-300 rounded w-3/4 mt-2" /> <div className="h-4 bg-gray-300 rounded w-1/2 mt-2" /> </div> ); }
Error States
// Clear, actionable error messages function ErrorMessage({ error, retry }) { return ( <div role="alert" className="error-banner"> <svg aria-hidden="true">⚠️</svg> <div> <h3>Something went wrong</h3> <p>{error.message}</p> </div> <button onClick={retry}>Try Again</button> </div> ); }
Success Feedback
-
Provide immediate visual confirmation
-
Use toast notifications for non-blocking feedback
-
Maintain context (don't navigate away immediately)
- Interaction Design
Button States
.button { /* Default state */ background: var(--primary); color: white; transition: all 150ms ease;
/* Hover state */ &:hover { background: var(--primary-hover); transform: translateY(-1px); }
/* Active state */ &:active { transform: translateY(0); }
/* Disabled state */ &:disabled { opacity: 0.5; cursor: not-allowed; }
/* Loading state */ &[aria-busy="true"] { position: relative; color: transparent; } }
Microinteractions
-
Provide subtle feedback for user actions
-
Use transitions for state changes
-
Keep animations under 300ms for responsiveness
/* Card hover effect */ .card { transition: transform 200ms ease, box-shadow 200ms ease; }
.card:hover { transform: translateY(-4px); box-shadow: 0 12px 24px rgba(0, 0, 0, 0.1); }
- Form Design
User-Friendly Forms
<form> <!-- Label association --> <label for="email"> Email Address <span aria-label="required">*</span> </label> <input id="email" type="email" required autocomplete="email" placeholder="you@example.com" aria-describedby="email-hint" /> <small id="email-hint">We'll never share your email</small>
<!-- Inline validation --> <div role="alert" id="email-error" class="hidden"> Please enter a valid email address </div> </form>
Form Best Practices
-
One column layout on mobile
-
Group related fields
-
Show validation inline and on submit
-
Disable submit button during processing
-
Preserve user input on errors
- Color Theory
Color Palette Structure
:root { /* Primary palette (brand) / --primary-50: #eff6ff; --primary-500: #3b82f6; / Main brand color */ --primary-900: #1e3a8a;
/* Semantic colors */ --success: #10b981; --warning: #f59e0b; --danger: #ef4444; --info: #3b82f6;
/* Neutral palette */ --gray-50: #f9fafb; --gray-500: #6b7280; --gray-900: #111827;
/* Text colors */ --text-primary: var(--gray-900); --text-secondary: var(--gray-600); --text-tertiary: var(--gray-400); }
Dark Mode Support
@media (prefers-color-scheme: dark) { :root { --text-primary: var(--gray-50); --text-secondary: var(--gray-400); --bg-primary: var(--gray-900); --bg-secondary: var(--gray-800); } }
- Typography
Typographic Scale
:root { /* Type scale (1.25 ratio) / --text-xs: 0.75rem; / 12px / --text-sm: 0.875rem; / 14px / --text-base: 1rem; / 16px / --text-lg: 1.25rem; / 20px / --text-xl: 1.5rem; / 24px / --text-2xl: 1.875rem; / 30px / --text-3xl: 2.25rem; / 36px */
/* Line heights */ --leading-tight: 1.25; --leading-normal: 1.5; --leading-relaxed: 1.75; }
Readable Text
-
Optimal line length: 50-75 characters
-
Line height: 1.5-1.75 for body text
-
Sufficient contrast (4.5:1 minimum)
Design Patterns
Card Pattern
function Card({ title, description, action, image }) { return ( <article className="card"> {image && <img src={image} alt="" className="card-image" />} <div className="card-content"> <h3 className="card-title">{title}</h3> <p className="card-description">{description}</p> </div> {action && ( <footer className="card-footer"> <button>{action.label}</button> </footer> )} </article> ); }
Modal Pattern
function Modal({ isOpen, onClose, title, children }) { if (!isOpen) return null;
return ( <div className="modal-overlay" onClick={onClose} role="dialog" aria-modal="true" aria-labelledby="modal-title" > <div className="modal-content" onClick={(e) => e.stopPropagation()} > <header className="modal-header"> <h2 id="modal-title">{title}</h2> <button onClick={onClose} aria-label="Close modal" > × </button> </header> <div className="modal-body">{children}</div> </div> </div> ); }
UX Best Practices
-
Progressive Disclosure - Show only what's necessary, reveal details on demand
-
Consistent Navigation - Keep navigation in expected locations
-
Forgiving Design - Allow undo, confirm destructive actions
-
Performance Perception - Use optimistic updates, skeleton screens
-
Mobile Gestures - Support swipe, pinch-to-zoom where appropriate
Design System Checklist
When building a design system:
-
Color palette with semantic naming
-
Typography scale and font families
-
Spacing scale (4px or 8px base)
-
Component library with consistent API
-
Accessibility guidelines
-
Dark mode support
-
Documentation with live examples
-
Design tokens (CSS variables or similar)
Tools and Resources
-
Design Tools: Figma, Adobe XD
-
Accessibility: axe DevTools, WAVE
-
Color Contrast: WebAIM Contrast Checker
-
Typography: Modular Scale Calculator
-
Icons: Heroicons, Lucide, Phosphor
Anti-Patterns to Avoid
❌ Low contrast text ❌ Tiny touch targets on mobile (minimum 44×44px) ❌ Removing focus outlines without alternative ❌ Auto-playing media without controls ❌ Using color alone to convey information ❌ Horizontal scrolling (except carousels) ❌ Opening links in new tabs without indication