CSS Responsive Design Guide

Responsive web design is an approach to web design that makes web pages render well on a variety of devices and window or screen sizes. This guide covers core responsive design principles and techniques using CSS.

1. Core Principles of Responsive Design

What Makes a Design Responsive?

Viewport Meta Tag

Always include the viewport meta tag in your HTML to ensure proper scaling on mobile devices:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

This tag tells the browser to set the width of the viewport to the device width and set the initial zoom level to 1.

Mobile-First vs. Desktop-First

Mobile-First Approach
/* Base styles for mobile */
.element {
  width: 100%;
  font-size: 16px;
}

/* Enhance for larger screens */
@media (min-width: 768px) {
  .element {
    width: 50%;
    font-size: 18px;
  }
}

Start with styles for mobile devices, then use min-width media queries to enhance for larger screens.

Desktop-First Approach
/* Base styles for desktop */
.element {
  width: 50%;
  font-size: 18px;
}

/* Adapt for smaller screens */
@media (max-width: 768px) {
  .element {
    width: 100%;
    font-size: 16px;
  }
}

Start with styles for desktop, then use max-width media queries to adapt for smaller screens.

2. Fluid Layouts

Fluid layouts use relative units instead of fixed pixels to create designs that adapt to different screen sizes.

Fluid Units in CSS

Percentages (%)
.container {
  width: 80%; /* Relative to parent element */
  margin: 0 auto;
}

.column {
  width: 33.333%; /* One-third of parent */
  float: left;
}
Viewport Units
.hero {
  width: 100vw; /* 100% viewport width */
  height: 50vh; /* 50% viewport height */
}

.text {
  font-size: 5vmin; /* Relative to smaller dimension */
}
EM and REM Units
html {
  font-size: 16px; /* Base font size */
}

.container {
  width: 50em; /* Relative to font size of container */
}

h1 {
  font-size: 2rem; /* Relative to root font size */
  margin-bottom: 1.5rem;
}

p {
  font-size: 1rem;
  line-height: 1.5;
}

Fluid Layout Example

Fluid Columns

Column 1
Column 2
Column 3
.fluid-columns {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.fluid-column {
  flex: 1; /* Grows to fill available space */
  min-width: 200px; /* Ensures columns wrap on small screens */
}

The Box-Sizing Property

/* Apply box-sizing to all elements */
*, *:before, *:after {
  box-sizing: border-box;
}

The box-sizing: border-box; property includes padding and border in an element's total width and height, making it easier to create consistent layouts.

Using max-width and min-width

.container {
  width: 80%;
  max-width: 1200px; /* Prevents getting too wide */
  min-width: 320px; /* Prevents getting too narrow */
  margin: 0 auto;
}

Using max-width and min-width helps control element sizing across different devices.

3. Responsive Typography

Responsive typography ensures text is readable across different screen sizes.

Font Size Units

Relative Units (rem/em)

Heading (2em)

Paragraph text (1em) that scales with the base font size of the parent element.

html {
  font-size: 16px; /* Base size */
}

.responsive-text h1 {
  font-size: 2em; /* 32px */
}

.responsive-text p {
  font-size: 1em; /* 16px */
}
Viewport Units for Type

Responsive Heading

This paragraph uses viewport units to scale based on screen width.

.clamp-heading {
  font-size: clamp(1.5rem, 5vw, 3rem);
}

.clamp-paragraph {
  font-size: clamp(1rem, 2vw, 1.25rem);
}

Fluid Typography with clamp()

The clamp() function creates fluid typography with minimum and maximum bounds:

h1 {
  /* Minimum: 1.5rem, Preferred: 5vw, Maximum: 3rem */
  font-size: clamp(1.5rem, 5vw, 3rem);
}

p {
  font-size: clamp(1rem, calc(0.875rem + 0.5vw), 1.25rem);
  line-height: 1.5;
}

Media Queries for Typography

/* Base typography */
body {
  font-size: 16px;
}

h1 {
  font-size: 2rem;
}

/* Adjustments for larger screens */
@media (min-width: 768px) {
  body {
    font-size: 18px;
  }
  
  h1 {
    font-size: 2.5rem;
  }
}

Responsive Line Heights

p {
  font-size: 1rem;
  line-height: 1.5; /* Unitless value is best practice */
}

h1 {
  font-size: 2.5rem;
  line-height: 1.2;
}

Using unitless line-height values allows for proper scaling with font size changes.

4. Media Queries

Media queries allow you to apply different styles based on device characteristics like screen width, height, or orientation.

Media Query Syntax

@media media-type and (media-feature) {
  /* CSS rules */
}

Common Media Features

Media Query Example

This element changes color at different breakpoints.
Blue: Default (above 768px)
Green: Below 768px
Red: Below 480px
.media-queries-demo {
  background-color: #3498db; /* Default (large screens) */
}

@media (max-width: 768px) {
  .media-queries-demo {
    background-color: #2ecc71; /* Medium screens */
  }
}

@media (max-width: 480px) {
  .media-queries-demo {
    background-color: #e74c3c; /* Small screens */
  }
}

Common Breakpoints

While breakpoints should be based on your design needs, here are some common ones:

/* Mobile first approach */
/* Base styles for mobile */

/* Small tablets and large phones */
@media (min-width: 576px) { ... }

/* Tablets and small laptops */
@media (min-width: 768px) { ... }

/* Desktops and laptops */
@media (min-width: 992px) { ... }

/* Large desktops */
@media (min-width: 1200px) { ... }

Combining Media Queries

/* Targets screens between 768px and 1024px */
@media (min-width: 768px) and (max-width: 1024px) { ... }

/* Targets screens in landscape mode */
@media (orientation: landscape) { ... }

/* Logical operators */
@media (min-width: 768px) and (orientation: landscape) { ... }
@media (min-width: 768px), (orientation: landscape) { ... }

Feature Queries (@supports)

/* Check if a CSS property is supported */
@supports (display: grid) {
  .container {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  }
}

/* Fallback for browsers that don't support grid */
@supports not (display: grid) {
  .container {
    display: flex;
    flex-wrap: wrap;
  }
  
  .item {
    width: calc(33.333% - 20px);
    margin: 10px;
  }
}

5. Responsive Images

Responsive images scale appropriately for different screen sizes and load optimized versions based on device capabilities.

Basic Responsive Images

Placeholder image
.responsive-image {
  max-width: 100%; /* Never exceed container width */
  height: auto; /* Maintain aspect ratio */
  display: block; /* Remove extra space below image */
}

The picture Element

The picture element provides more control over image loading based on media conditions:

<picture>
  <source media="(min-width: 1024px)" srcset="large.jpg">
  <source media="(min-width: 768px)" srcset="medium.jpg">
  <img src="small.jpg" alt="Description" class="responsive-image">
</picture>

Responsive Background Images

.hero {
  width: 100%;
  height: 50vh;
  background-image: url('small.jpg');
  background-size: cover;
  background-position: center;
}

@media (min-width: 768px) {
  .hero {
    background-image: url('medium.jpg');
  }
}

@media (min-width: 1200px) {
  .hero {
    background-image: url('large.jpg');
  }
}

Art Direction with srcset and sizes

<img 
  src="small.jpg" 
  srcset="small.jpg 320w, medium.jpg 768w, large.jpg 1200w" 
  sizes="(max-width: 320px) 280px, (max-width: 768px) 720px, 1140px"
  alt="Description"
>

This tells the browser which image to load based on the viewport size and device resolution.

6. CSS Layout Techniques

Modern CSS provides powerful tools for creating responsive layouts.

CSS Grid

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
.responsive-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
  gap: 15px;
}

Grid creates two-dimensional layouts that can automatically adjust based on available space. The minmax() and auto-fill/auto-fit functions are particularly useful for responsive designs.

Flexbox

Item 1
Item 2
Item 3
Item 4
.flex-container {
  display: flex;
  flex-wrap: wrap;
  gap: 15px;
}

.flex-item {
  flex: 1 1 200px; /* grow shrink basis */
}

Flexbox excels at one-dimensional layouts and is ideal for navigation bars, card layouts, and vertically centered content.

Multi-column Layout

.text-columns {
  column-count: 3;
  column-gap: 2em;
}

@media (max-width: 768px) {
  .text-columns {
    column-count: 2;
  }
}

@media (max-width: 480px) {
  .text-columns {
    column-count: 1;
  }
}

Multi-column layout is useful for flowing text in newspaper-like columns that adjust based on screen size.

Combining Layout Methods

.page {
  display: grid;
  grid-template-areas:
    "header header"
    "sidebar content"
    "footer footer";
  grid-template-columns: 1fr 3fr;
  gap: 20px;
}

@media (max-width: 768px) {
  .page {
    grid-template-areas:
      "header"
      "content"
      "sidebar"
      "footer";
    grid-template-columns: 1fr;
  }
}

.header { grid-area: header; }
.sidebar { grid-area: sidebar; }
.content { grid-area: content; }
.footer { grid-area: footer; }

/* Using flexbox within grid areas */
.content {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

7. Advanced Responsive Techniques

Container Queries

Container queries allow styles to be applied based on the size of a parent container rather than the viewport, enabling truly modular responsive components.

Resize this container horizontally to see the layout change (requires browser support).

Sidebar
Main Content
/* Example Container Query Syntax (modern browsers) */
.container {
  container-type: inline-size;
  container-name: sidebar-layout;
}

@container sidebar-layout (min-width: 700px) {
  .layout {
    display: flex;
  }
  
  .sidebar {
    width: 200px;
  }
}

@container sidebar-layout (max-width: 699px) {
  .layout {
    display: block;
  }
  
  .sidebar {
    width: 100%;
  }
}

Viewport Units

Viewport Units Demo
.viewport-units-demo {
  width: 80vw; /* 80% of viewport width */
  height: 40vh; /* 40% of viewport height */
  font-size: 3vmin; /* 3% of viewport's smaller dimension */
}

Viewport units (vw, vh, vmin, vmax) size elements relative to the viewport dimensions.

Responsive Aspect Ratios

/* Modern approach with aspect-ratio property */
.video-container {
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
}

/* Older approach with padding hack */
.video-container-legacy {
  width: 100%;
  position: relative;
  padding-bottom: 56.25%; /* 16:9 aspect ratio (9/16 = 0.5625) */
}

.video-container-legacy iframe {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}

Detecting Touch Capabilities

/* Media query for touch devices */
@media (hover: none) and (pointer: coarse) {
  /* Styles for touch devices */
  .button {
    padding: 12px 24px; /* Larger touch target */
  }
}

@media (hover: hover) {
  /* Styles for devices with hover capability */
  .card:hover {
    transform: translateY(-5px);
  }
}

8. Practical Responsive Design Patterns

Responsive Navigation

.navbar {
  background-color: #2c3e50;
  color: white;
}

.nav-container {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.nav-menu {
  display: flex;
  gap: 20px;
}

.nav-toggle {
  display: none; /* Hidden on desktop */
}

@media (max-width: 768px) {
  .nav-menu {
    position: fixed;
    left: -100%;
    top: 70px;
    flex-direction: column;
    width: 100%;
    text-align: center;
    transition: 0.3s;
    padding: 20px 0;
  }
  
  .nav-menu.active {
    left: 0;
  }
  
  .nav-toggle {
    display: block; /* Visible on mobile */
  }
}

Card Layouts

Image

Card 1

This is a responsive card layout that adjusts based on screen size.

Image

Card 2

Cards will wrap to new rows when there's not enough space.

Image

Card 3

Each card has a minimum width but will grow to fill available space.

.card-container {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}

.card {
  flex: 1 1 300px; /* grow shrink basis */
}

Responsive Tables

Name Age Location Occupation
John Doe 32 New York Developer
Jane Smith 28 London Designer
Bob Johnson 45 Paris Manager
/* Basic responsive table with horizontal scrolling */
.responsive-table {
  width: 100%;
  border-collapse: collapse;
}

@media (max-width: 768px) {
  .responsive-table {
    display: block;
    overflow-x: auto;
  }
}

/* Card-based approach for very small screens */
@media (max-width: 480px) {
  .responsive-table, .responsive-table tbody, .responsive-table tr, 
  .responsive-table th, .responsive-table td {
    display: block;
    width: 100%;
  }
  
  .responsive-table td {
    position: relative;
    padding-left: 50%;
  }
  
  .responsive-table td:before {
    position: absolute;
    left: 12px;
    width: 45%;
    font-weight: bold;
    content: attr(data-label);
  }
}

9. Testing Responsive Designs

Testing Methods

  1. Browser DevTools: Use Chrome, Firefox, or Edge's built-in responsive design mode.
  2. Actual Devices: Test on real phones, tablets, and computers when possible.
  3. Online Testing Tools: Services like BrowserStack or Responsively App.
  4. Accessibility Testing: Ensure your responsive design works well with screen readers and keyboard navigation.

Common Responsive Issues to Check

10. Browser Support and Fallbacks

Supporting Older Browsers

Feature Support Examples

CSS Grid

Two-dimensional layout system

Chrome
Firefox
Safari
IE11*
Flexbox

One-dimensional layout

Chrome
Firefox
Safari
IE11*
Container Queries

Component-level responsive design

Chrome
Firefox
Safari
IE11

Progressive Enhancement Example

/* Base styles everyone gets */
.layout {
  display: block;
}

.column {
  width: 100%;
  margin-bottom: 20px;
}

/* Flexbox enhancement */
@supports (display: flex) {
  .layout {
    display: flex;
    flex-wrap: wrap;
    gap: 20px;
  }
  
  .column {
    flex: 1 1 300px;
    margin-bottom: 0;
  }
}

/* Grid enhancement */
@supports (display: grid) {
  .layout {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 20px;
  }
  
  .column {
    /* No need for flex properties */
  }
}