Overview
Responsive design represents an approach to web development where interfaces automatically adjust their layout, content, and functionality based on the device's screen size, orientation, and capabilities. This methodology addresses the fragmentation of web access across smartphones, tablets, desktops, and other devices by creating a single codebase that serves all platforms.
The concept emerged from the need to replace separate mobile and desktop websites with unified solutions. Traditional approaches maintained distinct codebases: one for m.example.com and another for www.example.com. Responsive design eliminates this duplication through CSS media queries, flexible grid systems, and adaptive images that reconfigure themselves based on viewport dimensions.
Three technical pillars support responsive design: fluid grids that use relative units instead of fixed pixels, flexible images that scale within their containers, and media queries that apply different styles at specific breakpoints. These components work together to create interfaces that function across the spectrum of screen sizes from 320-pixel smartphones to 4K desktop monitors.
/* Fluid grid example */
.container {
width: 90%;
max-width: 1200px;
margin: 0 auto;
}
.column {
width: 100%;
}
@media (min-width: 768px) {
.column {
width: 48%;
float: left;
margin: 1%;
}
}
The viewport meta tag controls how browsers render pages on mobile devices. Without this tag, mobile browsers render pages at desktop widths and scale them down, creating tiny, unreadable text. The viewport tag instructs the browser to match the screen width and prevents unwanted zoom behavior.
<meta name="viewport" content="width=device-width, initial-scale=1.0">
Responsive design differs from adaptive design, which serves distinct layouts at predetermined breakpoints rather than continuously adjusting. Adaptive design detects the device and serves pre-built layouts, while responsive design fluidly transforms as the viewport changes. Both approaches have valid use cases, but responsive design requires less maintenance since it works across any screen size, including devices that don't exist yet.
Key Principles
Fluid Grids
Fluid grids replace fixed-width layouts with proportional sizing using percentages, em, rem, or viewport units. Instead of defining a column as 960 pixels wide, it becomes 80% of the viewport or calculated using CSS Grid's fr units. This proportional approach allows layouts to scale naturally across different screen sizes.
The formula for converting fixed layouts to fluid grids: target / context = result. For a 300-pixel element in a 960-pixel container: 300 / 960 = 0.3125 or 31.25%. This calculation applies to all spatial relationships including margins, padding, and positioning.
/* Fixed layout */
.sidebar {
width: 300px;
}
.content {
width: 660px;
}
/* Fluid equivalent */
.sidebar {
width: 31.25%; /* 300 / 960 */
}
.content {
width: 68.75%; /* 660 / 960 */
}
Flexible Images and Media
Images pose challenges in responsive layouts because they have intrinsic dimensions. Setting max-width: 100% and height: auto allows images to scale down to fit their container while maintaining aspect ratio. This prevents images from overflowing their containers on small screens.
img, video, iframe {
max-width: 100%;
height: auto;
}
The picture element provides more control by serving different images at different breakpoints. This optimizes bandwidth and ensures appropriate image sizes for each device. A 2000-pixel image wastes bandwidth on a 375-pixel phone screen.
<picture>
<source media="(min-width: 1200px)" srcset="large.jpg">
<source media="(min-width: 768px)" srcset="medium.jpg">
<img src="small.jpg" alt="Description">
</picture>
Media Queries
Media queries apply CSS rules conditionally based on device characteristics. The most common query tests viewport width, but queries can also check height, orientation, resolution, and color capabilities. Media queries form the foundation of breakpoint-based responsive design.
/* Base styles for mobile */
.navigation {
display: block;
}
.nav-item {
display: block;
padding: 1rem;
}
/* Tablet and larger */
@media (min-width: 768px) {
.navigation {
display: flex;
}
.nav-item {
display: inline-block;
padding: 0 1rem;
}
}
Breakpoints
Breakpoints define viewport widths where layouts change. Common breakpoints occur at 576px (small phones to large phones), 768px (tablets), 992px (small desktops), and 1200px (large desktops). These values originated from common device sizes but should be determined by content needs rather than specific devices.
Content-based breakpoints prove more maintainable than device-based breakpoints. When text becomes too wide to read comfortably or layouts break, add a breakpoint. This approach remains valid as new devices with different dimensions enter the market.
Mobile-First vs Desktop-First
Mobile-first design writes base styles for small screens and uses min-width media queries to add complexity for larger screens. Desktop-first design writes base styles for large screens and uses max-width queries to simplify for smaller screens. Mobile-first forces progressive enhancement and often results in cleaner code.
/* Mobile-first approach */
.container {
padding: 1rem;
}
@media (min-width: 768px) {
.container {
padding: 2rem;
}
}
@media (min-width: 1200px) {
.container {
padding: 3rem;
}
}
/* Desktop-first approach */
.container {
padding: 3rem;
}
@media (max-width: 1199px) {
.container {
padding: 2rem;
}
}
@media (max-width: 767px) {
.container {
padding: 1rem;
}
}
Touch Targets
Interactive elements require larger hit areas on touchscreens than on desktop pointer devices. Buttons and links should measure at least 44×44 pixels to accommodate average finger sizes. Insufficient spacing between touch targets causes mis-taps and user frustration.
Viewport Units
Viewport units (vw, vh, vmin, vmax) size elements relative to the viewport dimensions. 1vw equals 1% of viewport width, 1vh equals 1% of viewport height. These units create truly responsive typography and layouts that scale with the viewport without media queries.
.hero-title {
font-size: calc(2rem + 2vw);
}
Design Considerations
Mobile-First Strategy
Mobile-first design starts with the smallest screens and progressively enhances for larger viewports. This approach prioritizes essential content and functionality, reducing bloat and improving performance on constrained devices. The philosophy assumes limited screen real estate and bandwidth as the baseline.
Benefits include faster initial page loads since base styles are minimal, forced content prioritization, and graceful degradation when JavaScript fails. Mobile-first development identifies truly essential features since non-critical elements get added only for larger screens.
Drawbacks include more media queries in the final CSS since each breakpoint adds styles rather than overriding them. Desktop-centric teams may find the paradigm shift challenging when accustomed to designing for large screens first.
Desktop-First Strategy
Desktop-first design builds for large screens and simplifies progressively for smaller viewports. This approach suits applications where desktop users form the primary audience or where complex interfaces require significant screen real estate.
Benefits include simpler initial development for desktop-focused products and easier adaptation of existing desktop-only sites. Some design patterns, like multi-column layouts with extensive navigation, translate more naturally from desktop to mobile than vice versa.
Drawbacks include larger initial payloads since mobile devices download desktop styles first, tendency to hide rather than redesign content for mobile, and risk of delivering sub-optimal mobile experiences as an afterthought.
Breakpoint Selection
Breakpoints should reflect content needs rather than specific devices. Resize the browser and add breakpoints where layouts break or become uncomfortable to use. This content-first approach creates more maintainable designs that work on any device.
Common breakpoint ranges:
- 0-575px: Extra small (phones)
- 576-767px: Small (large phones)
- 768-991px: Medium (tablets)
- 992-1199px: Large (desktops)
- 1200px+: Extra large (large desktops)
These values serve as guidelines, not requirements. An article-focused site might need fewer breakpoints than a complex dashboard application. Some designs function well with just two breakpoints, while others require five or more.
Content Choreography
Content choreography describes how content reflows at different breakpoints. On mobile, stacked vertical layouts work best. On tablets, two-column layouts become viable. On desktops, multi-column layouts with sidebars appear.
Priority determines which content appears first in the source order. Mobile users should encounter the most important content before scrolling. CSS Grid and Flexbox allow visual reordering without changing HTML structure, but source order still matters for accessibility and SEO.
Performance Trade-offs
Responsive design introduces performance considerations. Serving the same large images to all devices wastes bandwidth on mobile. Loading desktop CSS on mobile increases page weight. These issues require mitigation through responsive images, critical CSS, and lazy loading.
The decision between client-side and server-side responsiveness affects performance. Client-side approaches use media queries and JavaScript, downloading all assets and selectively displaying them. Server-side approaches detect the device and send only relevant code, reducing payload but requiring server logic.
Progressive Enhancement vs Graceful Degradation
Progressive enhancement builds a baseline experience that works everywhere, then adds enhancements for capable devices. Start with semantic HTML that functions without CSS or JavaScript, add responsive styles, then layer interactive features.
Graceful degradation designs for modern browsers first, ensuring the experience degrades acceptably on older devices. This approach risks delivering broken experiences to users with JavaScript disabled or unsupported browsers.
Progressive enhancement aligns better with responsive design philosophy since both prioritize core functionality and progressively add complexity.
Ruby Implementation
Rails Asset Pipeline and Responsive CSS
Rails applications serve responsive CSS through the asset pipeline, which concatenates and minifies stylesheets. Place responsive styles in app/assets/stylesheets/ with organization reflecting the component structure.
# app/assets/stylesheets/application.css
/*
*= require_tree .
*= require_self
*/
The viewport meta tag belongs in the application layout:
<!-- app/views/layouts/application.html.erb -->
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<%= stylesheet_link_tag "application", media: "all" %>
<%= javascript_include_tag "application" %>
</head>
<body>
<%= yield %>
</body>
</html>
Device Detection in Rails
The browser gem identifies devices and capabilities, enabling server-side responsive decisions. Install it with gem 'browser' and use it in controllers or helpers.
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_action :set_device_type
private
def set_device_type
@mobile = browser.device.mobile?
@tablet = browser.device.tablet?
@desktop = !@mobile && !@tablet
end
end
# app/helpers/application_helper.rb
module ApplicationHelper
def responsive_image_tag(image_path, options = {})
if @mobile
image_tag("#{image_path}-small.jpg", options)
elsif @tablet
image_tag("#{image_path}-medium.jpg", options)
else
image_tag("#{image_path}-large.jpg", options)
end
end
end
Responsive Images with Active Storage
Active Storage generates image variants at different sizes, delivering appropriate versions based on viewport. Define variants in the model and use them in views.
# app/models/article.rb
class Article < ApplicationRecord
has_one_attached :hero_image
def hero_image_variants
{
small: hero_image.variant(resize_to_limit: [640, 480]),
medium: hero_image.variant(resize_to_limit: [1024, 768]),
large: hero_image.variant(resize_to_limit: [1920, 1080])
}
end
end
# app/views/articles/show.html.erb
<picture>
<source media="(min-width: 1200px)"
srcset="<%= url_for(@article.hero_image_variants[:large]) %>">
<source media="(min-width: 768px)"
srcset="<%= url_for(@article.hero_image_variants[:medium]) %>">
<img src="<%= url_for(@article.hero_image_variants[:small]) %>"
alt="<%= @article.title %>">
</picture>
Responsive Tables
Tables present challenges on small screens since they require horizontal space. Rails helpers can generate responsive table markup that transforms into a card-based layout on mobile.
# app/helpers/table_helper.rb
module TableHelper
def responsive_table(&block)
content_tag(:div, class: 'table-responsive') do
content_tag(:table, class: 'table', &block)
end
end
end
# app/views/products/index.html.erb
<%= responsive_table do %>
<thead>
<tr>
<th>Name</th>
<th>Price</th>
<th>Stock</th>
</tr>
</thead>
<tbody>
<% @products.each do |product| %>
<tr>
<td data-label="Name"><%= product.name %></td>
<td data-label="Price"><%= number_to_currency(product.price) %></td>
<td data-label="Stock"><%= product.stock %></td>
</tr>
<% end %>
</tbody>
<% end %>
Corresponding CSS transforms the table on mobile:
@media (max-width: 767px) {
.table-responsive table,
.table-responsive thead,
.table-responsive tbody,
.table-responsive tr,
.table-responsive td {
display: block;
}
.table-responsive thead {
display: none;
}
.table-responsive td {
position: relative;
padding-left: 40%;
}
.table-responsive td:before {
content: attr(data-label);
position: absolute;
left: 0;
width: 35%;
padding-right: 10px;
font-weight: bold;
}
}
Viewport-Aware Navigation
Rails applications often require different navigation patterns for mobile and desktop. A helper method can generate appropriate markup.
# app/helpers/navigation_helper.rb
module NavigationHelper
def responsive_navigation(items)
content_tag(:nav, class: 'responsive-nav') do
concat(mobile_nav_toggle)
concat(nav_items(items))
end
end
private
def mobile_nav_toggle
content_tag(:button, class: 'nav-toggle', 'aria-label': 'Toggle navigation') do
content_tag(:span, class: 'hamburger') do
3.times.map { content_tag(:span) }.join.html_safe
end
end
end
def nav_items(items)
content_tag(:ul, class: 'nav-items') do
items.map do |item|
content_tag(:li, class: 'nav-item') do
link_to item[:text], item[:path], class: 'nav-link'
end
end.join.html_safe
end
end
end
Form Optimization
Mobile forms benefit from appropriate input types and attributes that trigger device-specific keyboards.
<%= form_with model: @user, local: true do |f| %>
<div class="form-group">
<%= f.label :email %>
<%= f.email_field :email,
autocomplete: 'email',
class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :phone %>
<%= f.telephone_field :phone,
autocomplete: 'tel',
class: 'form-control' %>
</div>
<div class="form-group">
<%= f.label :website %>
<%= f.url_field :website,
autocomplete: 'url',
class: 'form-control' %>
</div>
<%= f.submit 'Save', class: 'btn btn-primary btn-block-mobile' %>
<% end %>
Practical Examples
Responsive Navigation Menu
A navigation menu that displays horizontally on desktop and converts to a hamburger menu on mobile demonstrates core responsive principles.
<nav class="main-nav">
<div class="nav-container">
<a href="/" class="logo">Logo</a>
<button class="nav-toggle" aria-label="Toggle navigation">
<span></span>
<span></span>
<span></span>
</button>
<ul class="nav-menu">
<li><a href="/products">Products</a></li>
<li><a href="/services">Services</a></li>
<li><a href="/about">About</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</div>
</nav>
.nav-container {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem;
}
.nav-toggle {
display: none;
flex-direction: column;
width: 30px;
height: 24px;
background: transparent;
border: none;
cursor: pointer;
}
.nav-toggle span {
width: 100%;
height: 3px;
background: #333;
margin: 3px 0;
transition: 0.3s;
}
.nav-menu {
display: flex;
list-style: none;
margin: 0;
padding: 0;
gap: 2rem;
}
@media (max-width: 768px) {
.nav-toggle {
display: flex;
}
.nav-menu {
display: none;
flex-direction: column;
position: absolute;
top: 60px;
left: 0;
width: 100%;
background: white;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
padding: 1rem 0;
}
.nav-menu.active {
display: flex;
}
.nav-menu li {
padding: 0.5rem 1rem;
}
}
JavaScript toggles the menu visibility:
document.querySelector('.nav-toggle').addEventListener('click', function() {
document.querySelector('.nav-menu').classList.toggle('active');
});
Responsive Grid Layout
A product grid demonstrates fluid layouts that adjust column count based on viewport width.
<div class="product-grid">
<div class="product-card">
<img src="product1.jpg" alt="Product 1">
<h3>Product Name</h3>
<p class="price">$99.99</p>
<button class="btn">Add to Cart</button>
</div>
<!-- More product cards -->
</div>
.product-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1.5rem;
padding: 1rem;
}
@media (min-width: 576px) {
.product-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 992px) {
.product-grid {
grid-template-columns: repeat(3, 1fr);
}
}
@media (min-width: 1200px) {
.product-grid {
grid-template-columns: repeat(4, 1fr);
}
}
.product-card {
background: white;
border-radius: 8px;
padding: 1rem;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.product-card img {
width: 100%;
height: auto;
border-radius: 4px;
}
.btn {
width: 100%;
padding: 0.75rem;
margin-top: 1rem;
background: #007bff;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
Responsive Typography
Typography scales with viewport size using a combination of relative units and viewport units.
html {
font-size: 16px;
}
body {
font-size: 1rem;
line-height: 1.6;
}
h1 {
font-size: calc(1.5rem + 1.5vw);
line-height: 1.2;
margin-bottom: 1rem;
}
h2 {
font-size: calc(1.25rem + 1vw);
line-height: 1.3;
margin-bottom: 0.875rem;
}
p {
font-size: 1rem;
margin-bottom: 1rem;
max-width: 65ch;
}
@media (min-width: 768px) {
html {
font-size: 18px;
}
}
@media (min-width: 1200px) {
html {
font-size: 20px;
}
}
Responsive Hero Section
Hero sections require different layouts and image treatments across devices.
<section class="hero">
<picture class="hero-image">
<source media="(min-width: 1200px)" srcset="hero-large.jpg">
<source media="(min-width: 768px)" srcset="hero-medium.jpg">
<img src="hero-small.jpg" alt="Hero image">
</picture>
<div class="hero-content">
<h1>Welcome to Our Site</h1>
<p>Discover amazing products and services</p>
<a href="/products" class="btn-primary">Shop Now</a>
</div>
</section>
.hero {
position: relative;
min-height: 400px;
display: flex;
align-items: center;
justify-content: center;
}
.hero-image img {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
object-fit: cover;
z-index: -1;
}
.hero-content {
text-align: center;
color: white;
padding: 2rem;
background: rgba(0,0,0,0.5);
border-radius: 8px;
}
.hero-content h1 {
font-size: 2rem;
margin-bottom: 1rem;
}
.hero-content p {
font-size: 1.125rem;
margin-bottom: 1.5rem;
}
@media (min-width: 768px) {
.hero {
min-height: 600px;
}
.hero-content h1 {
font-size: 3rem;
}
.hero-content p {
font-size: 1.5rem;
}
}
Common Patterns
Container Query Pattern
Container queries allow components to respond to their container's size rather than the viewport. This enables truly modular components that adapt regardless of where they appear in the layout.
.card-container {
container-type: inline-size;
container-name: card;
}
.card {
padding: 1rem;
}
@container card (min-width: 400px) {
.card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 1rem;
}
}
Mobile-First Media Query Pattern
Mobile-first patterns establish mobile styles as the baseline and progressively enhance for larger screens.
/* Mobile base styles */
.sidebar {
width: 100%;
padding: 1rem;
}
/* Tablet enhancement */
@media (min-width: 768px) {
.sidebar {
width: 33.33%;
padding: 1.5rem;
}
}
/* Desktop enhancement */
@media (min-width: 1200px) {
.sidebar {
width: 25%;
padding: 2rem;
}
}
Flexbox Responsive Pattern
Flexbox creates responsive layouts that wrap naturally without explicit breakpoints.
.flex-container {
display: flex;
flex-wrap: wrap;
gap: 1rem;
}
.flex-item {
flex: 1 1 300px;
min-width: 0;
}
This pattern creates items that attempt to be 300 pixels wide but grow to fill available space and wrap to new rows when space constrains.
CSS Grid Auto-Fit Pattern
CSS Grid's auto-fit and minmax create responsive grids without media queries.
.grid-container {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
}
This creates a grid where columns are at least 250 pixels wide, filling available space with as many columns as fit, and automatically wrapping to new rows.
Responsive Image Pattern
The picture element pattern serves different images at different breakpoints for optimal bandwidth usage.
<picture>
<source media="(min-width: 1200px)"
srcset="image-large.jpg 1x, image-large-2x.jpg 2x">
<source media="(min-width: 768px)"
srcset="image-medium.jpg 1x, image-medium-2x.jpg 2x">
<img src="image-small.jpg"
srcset="image-small-2x.jpg 2x"
alt="Descriptive text">
</picture>
Responsive Utility Classes Pattern
Utility classes control visibility and layout at different breakpoints without writing custom CSS.
.hide-mobile {
display: none;
}
.hide-desktop {
display: block;
}
@media (min-width: 768px) {
.hide-mobile {
display: block;
}
.hide-desktop {
display: none;
}
}
Touch-Friendly Spacing Pattern
Touch interfaces require larger hit areas and increased spacing between interactive elements.
.button {
min-height: 44px;
min-width: 44px;
padding: 0.75rem 1.5rem;
margin: 0.5rem;
}
@media (pointer: coarse) {
.button {
min-height: 48px;
padding: 1rem 2rem;
margin: 0.75rem;
}
}
Performance Considerations
Image Optimization
Responsive images require careful optimization to avoid sending oversized assets to mobile devices. The srcset attribute enables browsers to select appropriate image sizes based on screen resolution and viewport width.
<img src="small.jpg"
srcset="small.jpg 400w,
medium.jpg 800w,
large.jpg 1200w"
sizes="(max-width: 768px) 100vw,
(max-width: 1200px) 50vw,
33vw"
alt="Responsive image">
The sizes attribute tells the browser what size the image will be at different viewport widths. The browser uses this information along with the device pixel ratio to select the optimal image from srcset. A 400-pixel-wide phone with 2x pixel density may download the 800-pixel image to display sharp imagery.
WebP and AVIF formats provide superior compression compared to JPEG and PNG. Serve modern formats to supporting browsers while falling back to traditional formats:
<picture>
<source type="image/avif" srcset="image.avif">
<source type="image/webp" srcset="image.webp">
<img src="image.jpg" alt="Fallback to JPEG">
</picture>
Lazy Loading
Lazy loading defers offscreen image loading until users scroll them into view, reducing initial page weight and improving perceived performance.
<img src="image.jpg" loading="lazy" alt="Description">
Native lazy loading works in modern browsers without JavaScript. For broader support or more control over loading behavior, use Intersection Observer:
const imageObserver = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const img = entry.target;
img.src = img.dataset.src;
img.classList.remove('lazy');
observer.unobserve(img);
}
});
});
document.querySelectorAll('img.lazy').forEach(img => {
imageObserver.observe(img);
});
Critical CSS
Critical CSS inlines above-the-fold styles in the HTML document, allowing initial render without waiting for external stylesheets. Remaining styles load asynchronously.
<head>
<style>
/* Critical CSS for above-the-fold content */
body { margin: 0; font-family: sans-serif; }
.header { background: #333; color: white; padding: 1rem; }
</style>
<link rel="preload" href="main.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
<noscript><link rel="stylesheet" href="main.css"></noscript>
</head>
Tools like Critical or Penthouse extract critical CSS automatically by rendering pages and identifying above-the-fold styles.
Reducing CSS Payload
Media queries increase CSS file size since all breakpoint styles download regardless of device. Conditional loading serves only relevant CSS to each device:
<link rel="stylesheet" href="base.css">
<link rel="stylesheet" href="mobile.css" media="(max-width: 767px)">
<link rel="stylesheet" href="tablet.css" media="(min-width: 768px) and (max-width: 1199px)">
<link rel="stylesheet" href="desktop.css" media="(min-width: 1200px)">
Browsers download all stylesheets but apply only matching ones. For true conditional delivery, use JavaScript or server-side detection.
JavaScript Performance
Responsive JavaScript should execute efficiently across devices with varying CPU capabilities. Debounce resize event handlers to prevent excessive function calls:
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
const handleResize = debounce(() => {
console.log('Window resized');
}, 250);
window.addEventListener('resize', handleResize);
Network Optimization
Mobile networks exhibit higher latency and lower bandwidth than wired connections. Minimize HTTP requests by combining files, using CSS sprites, and implementing HTTP/2 server push. Compress text assets with gzip or Brotli compression.
Service workers cache assets for offline access and faster subsequent loads:
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache => {
return cache.addAll([
'/',
'/styles/main.css',
'/scripts/main.js',
'/images/logo.svg'
]);
})
);
});
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request).then(response => {
return response || fetch(event.request);
})
);
});
Third-Party Resource Impact
Third-party scripts and embeds significantly impact performance. Load analytics, ads, and social widgets asynchronously and defer them until after critical content renders:
<script async src="analytics.js"></script>
<script defer src="non-critical.js"></script>
The async attribute loads scripts without blocking HTML parsing but executes them immediately upon download. The defer attribute delays execution until HTML parsing completes.
Reference
Media Query Breakpoints
| Breakpoint | Range | Typical Devices | Common Use |
|---|---|---|---|
| xs | 0-575px | Small phones | Single column, vertical stack |
| sm | 576-767px | Large phones | Single or two column |
| md | 768-991px | Tablets | Two to three column |
| lg | 992-1199px | Small desktops | Multi-column with sidebar |
| xl | 1200-1399px | Desktops | Full multi-column layout |
| xxl | 1400px+ | Large desktops | Wide multi-column layout |
Viewport Meta Tag Options
| Attribute | Values | Description |
|---|---|---|
| width | device-width, number | Sets viewport width in pixels |
| initial-scale | 0.1 to 10.0 | Initial zoom level |
| minimum-scale | 0.1 to 10.0 | Minimum allowed zoom |
| maximum-scale | 0.1 to 10.0 | Maximum allowed zoom |
| user-scalable | yes, no | Allow user pinch-to-zoom |
| viewport-fit | auto, contain, cover | Control safe area insets |
CSS Units for Responsive Design
| Unit | Type | Description | Use Case |
|---|---|---|---|
| % | Relative | Percentage of parent | Fluid widths |
| em | Relative | Relative to element font size | Scalable spacing |
| rem | Relative | Relative to root font size | Consistent scaling |
| vw | Viewport | 1% of viewport width | Full-width elements |
| vh | Viewport | 1% of viewport height | Full-height sections |
| vmin | Viewport | 1% of smaller viewport dimension | Responsive typography |
| vmax | Viewport | 1% of larger viewport dimension | Aspect ratio maintenance |
| ch | Relative | Width of the 0 character | Text containers |
| fr | Grid | Flexible grid fraction | CSS Grid layouts |
Touch Target Sizes
| Element Type | Minimum Size | Recommended Size | Spacing |
|---|---|---|---|
| Primary buttons | 44x44px | 48x48px | 8px |
| Secondary buttons | 40x40px | 44x44px | 8px |
| Text links | 44px height | 48px height | 8px vertical |
| Form inputs | 44px height | 48px height | 16px vertical |
| Icon buttons | 44x44px | 48x48px | 8px |
| Navigation items | 44px height | 48px height | 8px between items |
Image Format Comparison
| Format | Compression | Transparency | Animation | Best For |
|---|---|---|---|---|
| JPEG | Lossy | No | No | Photos, complex images |
| PNG | Lossless | Yes | No | Graphics, transparency needed |
| WebP | Both | Yes | Yes | Modern web, general purpose |
| AVIF | Both | Yes | Yes | Next-gen, superior compression |
| SVG | N/A | Yes | Yes | Logos, icons, illustrations |
Common Media Query Patterns
| Pattern | Code Example | Use Case |
|---|---|---|
| Min-width | @media (min-width: 768px) | Mobile-first approach |
| Max-width | @media (max-width: 767px) | Desktop-first approach |
| Width range | @media (min-width: 768px) and (max-width: 991px) | Tablet-specific styles |
| Orientation | @media (orientation: landscape) | Layout changes for orientation |
| Pointer type | @media (pointer: coarse) | Touch vs mouse input |
| Resolution | @media (min-resolution: 2dppx) | High-DPI displays |
| Prefers color scheme | @media (prefers-color-scheme: dark) | Dark mode support |
| Reduced motion | @media (prefers-reduced-motion: reduce) | Accessibility consideration |
Flexbox Responsive Properties
| Property | Values | Responsive Application |
|---|---|---|
| flex-direction | row, column | Stack vertically on mobile |
| flex-wrap | nowrap, wrap | Allow items to wrap |
| flex-basis | auto, length, percentage | Base size before growing |
| flex-grow | number | Allow items to expand |
| flex-shrink | number | Allow items to contract |
| gap | length | Responsive spacing |
| justify-content | flex-start, center, space-between | Horizontal alignment |
| align-items | flex-start, center, stretch | Vertical alignment |
Grid Responsive Properties
| Property | Values | Responsive Application |
|---|---|---|
| grid-template-columns | repeat, auto-fit, minmax | Automatic column adjustment |
| grid-template-rows | auto, fr, minmax | Flexible row heights |
| grid-auto-flow | row, column, dense | Content flow direction |
| gap | length | Responsive gutters |
| grid-template-areas | quoted strings | Named layout areas |
| justify-items | start, center, stretch | Item horizontal alignment |
| align-items | start, center, stretch | Item vertical alignment |
Performance Optimization Checklist
| Optimization | Implementation | Impact |
|---|---|---|
| Responsive images | srcset, picture element | Reduces bandwidth 50-70% |
| Lazy loading | loading=lazy attribute | Faster initial load |
| Critical CSS | Inline above-fold styles | Eliminates render blocking |
| Compress images | WebP, AVIF formats | 30-50% smaller files |
| Minify CSS/JS | Build tool minification | 20-40% smaller files |
| Enable compression | gzip, Brotli | 70-80% smaller transfer |
| CDN delivery | Content distribution network | Reduced latency |
| Cache assets | Service worker, HTTP cache | Instant repeat visits |