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¶
- Inline critical styles in
<head>
- Load non-critical styles asynchronously
- 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¶
- Lighthouse CI: Automated performance checks
- WebPageTest: Real device testing
- Chrome DevTools: Runtime performance
- 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); }
}
Navigation¶
/* 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 ✅¶
- Use logical properties for better internationalization
- Test on real devices not just browser DevTools
- Optimize images with responsive sizes
- Implement lazy loading for off-screen content
- Use CSS Grid and Flexbox for layouts
- Design for thumb reach on mobile devices
- Ensure readable text without zooming
Don'ts ❌¶
- Don't use pixels for typography (use rem/em)
- Don't hide critical content on mobile
- Don't rely on hover for essential functionality
- Don't use fixed widths for containers
- Don't forget landscape orientations
- Don't ignore performance budgets
- 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'; } }