Responsive Design Principles

Responsive design — UI that adapts to different screen sizes — is now the default. Single-screen-size designs are rare. The patterns have evolved: from breakpoint-heavy layouts to fluid, container-aware designs.

This page covers the modern principles.

Mobile-first

Design for small screens first; enhance for larger screens.

/* Default: mobile */
.card {
    padding: 16px;
}

/* Tablets and up */
@media (min-width: 768px) {
    .card {
        padding: 24px;
    }
}

/* Desktop and up */
@media (min-width: 1024px) {
    .card {
        padding: 32px;
    }
}

The mobile styles are the default. Larger screens add to them.

Why mobile-first:

Breakpoint patterns

Common breakpoints

These are conventions; actual breakpoints should match design needs, not arbitrary device sizes.

Don't design for specific devices

The "iPhone breakpoint" is wrong. Devices have many sizes; designing for specific phones leaves others poorly served.

Design for content. When the layout breaks down (text wraps oddly, columns squish), that's the breakpoint.

Fluid layout

Move from fixed values to fluid:

/* Old: fixed */
.container { width: 1200px; }

/* Fluid: relative units, max bound */
.container {
    width: 100%;
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 16px;
}

The container fills its parent up to 1200px, with margin to keep it centered.

Fluid typography

Type that scales with viewport:

h1 {
    font-size: clamp(1.5rem, 4vw, 3rem);
}

clamp(min, preferred, max):

Result: smooth typography across screen sizes without breakpoints.

CSS Grid

Grid changes layout fundamentally:

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
    gap: 16px;
}

auto-fit + minmax(300px, 1fr):

Naturally responsive without breakpoints. Cards reflow as the container width changes.

Container queries

Modern CSS feature. Style based on the container size, not the viewport:

.card-container {
    container-type: inline-size;
}

.card {
    /* Default */
}

@container (min-width: 400px) {
    .card {
        /* When the container is at least 400px wide */
    }
}

Container queries enable truly modular components — a card behaves the same whether it's in a sidebar or main content, based on its container, not the page.

This is the long-awaited fix for component-level responsive design.

Flexbox

For one-dimensional layouts:

.row {
    display: flex;
    gap: 16px;
    flex-wrap: wrap;
}

.row > * {
    flex: 1 1 200px;
}

Items distribute; wrap when they can't fit; minimum 200px each.

For most simple "row of items" layouts, flexbox is the right tool. For 2D layouts, grid.

Images

Responsive images use srcset:

<img src="image-800.jpg"
     srcset="image-400.jpg 400w,
             image-800.jpg 800w,
             image-1600.jpg 1600w"
     sizes="(min-width: 1024px) 50vw, 100vw"
     alt="Description">

The browser picks the right image based on device pixel density and the rendered size.

For art direction (different crops at different sizes), use <picture>.

Content prioritization

Mobile screens have less space. Decide what's essential:

The "show everything" approach produces unusable mobile experiences.

Performance considerations

Mobile users often have slower networks and less powerful devices. Responsive doesn't help if mobile-loaded resources are huge.

Strategies:

Common failure patterns

Modern defaults

For new responsive design:

  1. Mobile-first CSS
  2. Fluid layouts (max-width with relative widths)
  3. Fluid typography (clamp)
  4. Grid for 2D layouts; flexbox for 1D
  5. Container queries where component-level responsive is needed
  6. Responsive images with srcset
  7. Test on real devices

Further Reading