Learning LibraryWebsite Development LibraryTeens

Responsive design: one page for every screen

The same page gets opened on a phone held in one hand and a monitor on a desk. Responsive design means writing it once and having it fit both.

The big idea

Write the small-screen layout with plain classes, then add prefixed classes such as md: that apply only from a certain width up.

See it in code

1The basics

Start with the phone. Unprefixed classes apply at every width, so grid-cols-1 is the base layout. This preview is 390 pixels wide, like a phone:

html
<section class="p-6">
  <h2 class="text-2xl font-bold md:text-4xl">Missions</h2>
  <div class="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
    <div class="rounded-xl bg-white/5 p-6">Perseverance</div>
    <div class="rounded-xl bg-white/5 p-6">Webb</div>
    <div class="rounded-xl bg-white/5 p-6">Juno</div>
  </div>
</section>
The mobile layout: one column:

The md: classes are in the markup but inactive, because 390px is below the md breakpoint of 768px. Only the unprefixed classes are in effect.

2A step further

Here is the identical markup at 800 pixels. Past 768px, each md: class overrides the unprefixed one it sits beside:

html
<section class="p-6">
  <h2 class="text-2xl font-bold md:text-4xl">Missions</h2>
  <div class="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
    <div class="rounded-xl bg-white/5 p-6">Perseverance</div>
    <div class="rounded-xl bg-white/5 p-6">Webb</div>
    <div class="rounded-xl bg-white/5 p-6">Juno</div>
  </div>
</section>
The same code, past the breakpoint:

md:grid-cols-2 replaced one column with two, and md:text-4xl enlarged the title. Nothing was rewritten; the wider screen switched those classes on.

3On COSMOS

Breakpoints can show and hide things. hidden md:flex means invisible on phones and a flex row from md up. md:hidden is the reverse:

html
<header class="flex items-center justify-between bg-slate-900 px-6 py-4">
  <p class="text-lg font-bold text-violet-300">COSMOS</p>
  <nav class="hidden gap-6 text-sm font-medium text-slate-300 md:flex">
    <a href="#about">About</a>
    <a href="#missions">Missions</a>
    <a href="#spotlight">Spotlight</a>
  </nav>
  <button class="rounded-lg border border-white/10 px-3 py-2 md:hidden">☰</button>
</header>
The navbar on a phone: links hidden, menu button shown:

At 390px the links are hidden and the button is visible. On a wide screen they swap. Three links would have overflowed a phone, so the layout changes instead.

The same idea, everywhere

Designing for the tightest constraint first, then adding as room allows, works far beyond web pages: an app on a watch and a tablet, a report as a summary and a full version.

Try it yourself

Add lg:grid-cols-3 to the grid so a monitor gets three columns. Breakpoints stack: one column, then two from 768px, then three from 1024px.

The common mistake

Forgetting the colon, or designing desktop-first. mdgrid-cols-2 is ignored, and writing the wide layout unprefixed means undoing it for phones. Phone first, then add upward.

What it unlocks

Breakpoints most often change a grid or a flex layout. The menu button above needs a script to do anything, which is events.