Beyond Breakpoints

Early responsive design relied heavily on fixed breakpoints that targeted specific device widths. You would write styles for mobile, tablet, and desktop, and hope that covered the range of screens your users had. This approach was always fragile, and the explosion of device sizes has made it even more so.

Modern responsive design focuses on fluid layouts that adapt continuously rather than snapping between fixed states. The goal is to create designs that look good at any width, not just the three or four breakpoints you defined.

Fluid Typography

Fluid typography scales smoothly between a minimum and maximum size based on the viewport width. The clamp() function makes this straightforward.

h1 {
  font-size: clamp(1.75rem, 1rem + 2vw, 3rem);
}

body {
  font-size: clamp(1rem, 0.875rem + 0.5vw, 1.25rem);
}

The clamp() function accepts three values: a minimum, a preferred value that scales with the viewport, and a maximum. This ensures your text is readable on small screens without becoming absurdly large on wide monitors.

The Flexible Grid Pattern

A flexible grid adapts its column count based on available space without requiring any media queries. This is one of the most useful responsive patterns in CSS.

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

This single declaration creates a grid that fills each row with as many 300px-minimum columns as will fit, expanding them equally to use all available space. On narrow screens, items stack into a single column. On wider screens, they flow into multiple columns. No breakpoints required.

The Sidebar Layout

A common layout features a fixed-width sidebar alongside a flexible main content area. This can be achieved with CSS Grid and no media queries.

.with-sidebar {
  display: grid;
  grid-template-columns: fit-content(250px) minmax(0, 1fr);
  gap: 2rem;
}

When the container is too narrow to accommodate both the sidebar and a reasonable main content width, you can use a container query or a single media query to stack them vertically.

Responsive Spacing

Just as typography should scale fluidly, so should your spacing. Using clamp() for margins, padding, and gaps creates layouts that breathe appropriately at every size.

:root {
  --space-s: clamp(0.75rem, 0.5rem + 0.5vw, 1rem);
  --space-m: clamp(1.25rem, 1rem + 1vw, 2rem);
  --space-l: clamp(2rem, 1.5rem + 2vw, 4rem);
}

.section {
  padding-block: var(--space-l);
}

.stack > * + * {
  margin-block-start: var(--space-m);
}

Defining a scale of fluid spacing tokens keeps your design consistent and makes it easy to adjust spacing across the entire site from a single set of variables.

Practical Tips

Several practices help responsive designs work reliably:

  • Set images to max-width: 100% and height: auto so they never overflow their containers
  • Use min() and max() alongside clamp() to constrain element widths sensibly
  • Prefer intrinsic sizing with min-content, max-content, and fit-content over fixed widths
  • Test your layouts by resizing the browser slowly from narrow to wide, watching for awkward states between your breakpoints
  • Use container queries for components that need to adapt to their parent rather than the viewport

The best responsive designs are barely noticeable. They simply work, regardless of where or how they are viewed.