Skip to content

Responsive Design System

Overview

Our responsive design system delivers exceptional experiences across all devices through modern CSS features, fluid typography, and performance-first principles. This guide documents our approach to creating adaptive, accessible, and blazing-fast interfaces.

Core Principles

1. Mobile-First Development

  • Start with the smallest viewport
  • Progressively enhance for larger screens
  • Optimize for touch interactions
  • Prioritize performance on mobile networks

2. Fluid Everything

  • Typography scales smoothly with viewport
  • Spacing adapts to available space
  • Layouts flow naturally between breakpoints
  • No jarring transitions or jumps

3. Performance Budget

  • 100/100 Lighthouse scores target
  • <1s Time to Interactive
  • 0 Cumulative Layout Shift
  • 60fps smooth scrolling

4. Progressive Enhancement

  • Core functionality works everywhere
  • Enhanced features for capable browsers
  • Graceful degradation for older browsers
  • No JavaScript required for layout

Breakpoint Strategy

Container-Based Design

We use container queries for component-level responsiveness:

/* Container sizes */
--container-xs: 20rem;    /* 320px */
--container-sm: 40rem;    /* 640px */
--container-md: 48rem;    /* 768px */
--container-lg: 64rem;    /* 1024px */
--container-xl: 80rem;    /* 1280px */
--container-2xl: 96rem;   /* 1536px */

Traditional Breakpoints

For global layout changes:

/* Mobile First Breakpoints */
@media (min-width: 640px)  { /* Tablet Portrait */ }
@media (min-width: 768px)  { /* Tablet Landscape */ }
@media (min-width: 1024px) { /* Desktop */ }
@media (min-width: 1280px) { /* Wide Desktop */ }
@media (min-width: 1536px) { /* Ultra Wide */ }

Fluid Typography System

Scale Definition

Our typography uses clamp() for smooth scaling:

/* Base font size scales from 16px to 18px */
--font-size-base: clamp(1rem, 0.9rem + 0.5vw, 1.125rem);

/* Heading scales */
--font-size-h1: clamp(2.5rem, 2rem + 2.5vw, 3.5rem);
--font-size-h2: clamp(2rem, 1.7rem + 1.5vw, 2.5rem);
--font-size-h3: clamp(1.5rem, 1.3rem + 1vw, 2rem);

Implementation

/* Apply fluid typography */
body {
  font-size: var(--font-size-base);
  line-height: 1.6;
}

/* Responsive line height */
h1 {
  font-size: var(--font-size-h1);
  line-height: clamp(1.1, 1.2 - 0.1vw, 1.3);
}

Responsive Spacing

Fluid Space Scale

/* Space values that grow with viewport */
--space-xs: clamp(0.25rem, 0.2rem + 0.25vw, 0.5rem);
--space-sm: clamp(0.5rem, 0.4rem + 0.5vw, 0.75rem);
--space-md: clamp(1rem, 0.8rem + 1vw, 1.5rem);
--space-lg: clamp(1.5rem, 1.2rem + 1.5vw, 2rem);
--space-xl: clamp(2rem, 1.5rem + 2.5vw, 3rem);

Usage Patterns

/* Responsive padding */
.section {
  padding-block: var(--space-xl);
  padding-inline: var(--space-md);
}

/* Responsive gaps */
.grid {
  gap: var(--space-md);
}

Touch Interaction Patterns

Minimum Touch Targets

All interactive elements meet accessibility standards:

/* Touch target sizes */
--touch-target-min: 44px;         /* WCAG minimum */
--touch-target-comfortable: 48px; /* Recommended */
--touch-target-spacious: 56px;    /* Premium feel */

Implementation

/* Ensure touch targets */
button, a, input {
  min-height: var(--touch-target-min);
  min-width: var(--touch-target-min);
}

/* Larger targets on touch devices */
@media (pointer: coarse) {
  .nav-link {
    min-height: var(--touch-target-comfortable);
    padding: var(--space-sm) var(--space-md);
  }
}

Layout Patterns

1. Responsive Grid

.grid {
  display: grid;
  gap: var(--space-md);
  grid-template-columns:
    repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

2. Sidebar Layout

/* Stack on mobile, side-by-side on desktop */
.layout-sidebar {
  display: grid;
  gap: var(--space-lg);
}

@media (min-width: 768px) {
  .layout-sidebar {
    grid-template-columns: var(--sidebar-width) 1fr;
  }
}

3. Container Queries

/* Component adapts to its container */
.card-container {
  container-type: inline-size;
}

@container (min-width: 400px) {
  .card {
    display: grid;
    grid-template-columns: 1fr 2fr;
  }
}

Performance Optimization

CSS Containment

/* Improve rendering performance */
.content-section {
  contain: layout style;
}

/* Full containment for isolated components */
.widget {
  contain: strict;
}

Content Visibility

/* Lazy render off-screen content */
.section:not(:first-child) {
  content-visibility: auto;
  contain-intrinsic-size: auto 500px;
}

Critical CSS

  1. Inline critical styles in <head>
  2. Load non-critical styles asynchronously
  3. Use resource hints for fonts
<!-- Preload critical resources -->
<link rel="preload" href="/fonts/inter.woff2" as="font" crossorigin>
<link rel="preload" href="/css/critical.css" as="style">

<!-- Async load non-critical CSS -->
<link rel="preload" href="/css/responsive.css" as="style"
      onload="this.onload=null;this.rel='stylesheet'">

Testing Methodology

Device Testing Matrix

Device Category Viewport Range Key Considerations
Mobile Small 320-375px Touch targets, readability
Mobile Large 376-414px Standard smartphone
Tablet Portrait 768-834px Multi-column layouts
Tablet Landscape 1024-1366px Desktop-like experience
Desktop 1367-1920px Full features
Wide Desktop 1921px+ Maximum content width

Performance Testing

  1. Lighthouse CI: Automated performance checks
  2. WebPageTest: Real device testing
  3. Chrome DevTools: Runtime performance
  4. BrowserStack: Cross-browser validation

Testing Checklist

  • Touch targets ≥ 44x44px
  • Text remains readable (16px minimum)
  • No horizontal scroll at any breakpoint
  • Images load appropriately sized
  • Animations run at 60fps
  • No layout shift during load
  • Forms are touch-friendly
  • Navigation is accessible

Responsive Components

Tables

/* Responsive table pattern */
@container (max-width: 600px) {
  table { display: block; overflow-x: auto; }
}

/* Stack pattern for narrow viewports */
@container (max-width: 480px) {
  tr { display: flex; flex-direction: column; }
  td::before { content: attr(data-label); }
}
/* Mobile: Hamburger menu */
@media (max-width: 767px) {
  .nav { position: fixed; transform: translateX(-100%); }
  .nav.open { transform: translateX(0); }
}

/* Desktop: Horizontal menu */
@media (min-width: 768px) {
  .nav { display: flex; position: static; }
}

Images

/* Responsive images with aspect ratio */
.image-container {
  position: relative;
  aspect-ratio: 16 / 9;
}

img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

Best Practices

Do's ✅

  1. Use logical properties for better internationalization
  2. Test on real devices not just browser DevTools
  3. Optimize images with responsive sizes
  4. Implement lazy loading for off-screen content
  5. Use CSS Grid and Flexbox for layouts
  6. Design for thumb reach on mobile devices
  7. Ensure readable text without zooming

Don'ts ❌

  1. Don't use pixels for typography (use rem/em)
  2. Don't hide critical content on mobile
  3. Don't rely on hover for essential functionality
  4. Don't use fixed widths for containers
  5. Don't forget landscape orientations
  6. Don't ignore performance budgets
  7. Don't test only on high-end devices

Implementation Examples

Hero Section

.hero {
  min-height: clamp(50vh, 40vh + 10vw, 70vh);
  padding: var(--space-xl) var(--space-md);
  display: grid;
  place-items: center;
  text-align: center;
}

.hero__title {
  font-size: var(--font-size-4xl);
  max-inline-size: 20ch;
}

Card Grid

.card-grid {
  container-type: inline-size;
  display: grid;
  gap: var(--space-md);
  grid-template-columns:
    repeat(auto-fit, minmax(min(100%, 300px), 1fr));
}

@container (min-width: 900px) {
  .card-grid {
    grid-template-columns: repeat(3, 1fr);
  }
}

Responsive Form

.form-group {
  display: grid;
  gap: var(--space-sm);
}

@media (min-width: 640px) {
  .form-group--inline {
    grid-template-columns: 1fr 2fr;
    align-items: center;
  }
}

input, select, textarea {
  width: 100%;
  min-height: var(--touch-target-min);
  padding: var(--space-sm);
  font-size: max(16px, var(--font-size-base));
}

Debugging Tools

Responsive Grid Overlay

Toggle with Ctrl+Shift+G:

// Add to development builds only
document.addEventListener('keydown', (e) => {
  if (e.ctrlKey && e.shiftKey && e.key === 'G') {
    document.querySelector('.debug-grid').classList.toggle('active');
  }
});

Viewport Size Indicator

/* Development helper */
body::after {
  content: 'XS';
  position: fixed;
  bottom: 10px;
  right: 10px;
  background: rgba(0,0,0,0.8);
  color: white;
  padding: 5px 10px;
  font-size: 12px;
  z-index: 9999;
}

@media (min-width: 640px) { body::after { content: 'SM'; } }
@media (min-width: 768px) { body::after { content: 'MD'; } }
@media (min-width: 1024px) { body::after { content: 'LG'; } }
@media (min-width: 1280px) { body::after { content: 'XL'; } }

Resources