AniUI Academy

Mobile-First Design

Writing base CSS for the smallest screen and layering on complexity with min-width queries, why that's simpler than desktop-first, and touch-target/hover-state realities for phones.

8 min read

You've already learned @media syntax and how min-width/max-width breakpoints work. Mobile-first is a specific strategy for using them — which direction you build in, and why that direction tends to produce better, simpler CSS.

Two directions to build in

Desktop-first writes the full, complex layout as the base styles, then uses max-width queries to strip things down for smaller screens:

/* Base: assumes a wide screen */
.layout {
  display: grid;
  grid-template-columns: 240px 1fr 300px;
}
 
@media (max-width: 700px) {
  /* Undo the grid for narrow screens */
  .layout {
    display: block;
  }
}

Mobile-first flips the order. The base styles are the small, simple layout with no media query at all, and min-width queries add complexity back in as the screen grows:

/* Base: the small-screen layout, no query needed */
.layout {
  display: block;
}
 
@media (min-width: 700px) {
  /* Add the grid once there's room for it */
  .layout {
    display: grid;
    grid-template-columns: 240px 1fr 300px;
  }
}

Both examples produce the same two layouts at the same breakpoint. The difference is which one is the "default" and which one is the exception layered on top.

Why mobile-first tends to win

Two real, practical reasons, not just convention for its own sake:

A phone screen forces prioritization. With roughly 360px of width to work with, you cannot fit everything a wide desktop layout has room for. You're forced to decide what actually matters — is that secondary sidebar essential, or can it wait until there's room for it? Designing the constrained version first tends to produce a clearer sense of what the content's priorities actually are. Designing the roomy version first and then trying to cut it down for a phone often means fighting your own earlier decisions.

Progressive enhancement produces simpler CSS than override-heavy desktop-first. In the desktop-first example above, the max-width query has to undo a grid that was never appropriate for a phone in the first place — display: block canceling out grid-template-columns, and often several more undone properties as a real layout grows in complexity. Every override is a little bit of built-then-demolished work. Mobile-first never fights itself this way: the base is simple by construction, and each min-width query only ever adds capability the smaller screen didn't need, never undoes something you already wrote.

This doesn't mean desktop-first CSS is broken or that you'll never see it — plenty of real projects use it, especially retrofits of older sites that started life desktop-only. But when you're starting from scratch, mobile-first is the well-established default for good reason.

Touch targets: a real, checkable number

A cursor is a single pixel-precise point. A finger is not — it's roughly the size of a small coin, and tapping near the edge of a small target is a common source of misfires and mis-taps. This is a real accessibility concern with concrete guidance behind it, not just a stylistic preference.

WCAG 2.2 sets 24×24 CSS pixels as its target size minimum for interactive elements like buttons and links. 44×44 CSS pixels is a widely used, more comfortable target above that floor — not the only "correct" number, but a common one you'll see recommended across platform design guidelines. Either way, the practical takeaway is the same: don't make a tappable icon button 16 pixels square just because the icon inside it looks fine at that size. Give it enough padding to reach a reasonable target size, even if the visible icon stays small.

.icon-button {
  /* The icon itself might only be 16px, but padding brings
     the actual tappable area up to a reasonable size */
  padding: 14px;
  min-width: 44px;
  min-height: 44px;
}

Touch has no hover

A mouse can rest over an element without clicking it — that's what :hover detects. A finger on a touchscreen has no equivalent resting state: it's either not touching the screen, or it's already tapping. There is no "hovering" gesture on most touch devices.

This matters because it's tempting to build interactions that only reveal themselves on :hover — a dropdown menu that appears when you mouse over a nav item, a tooltip that only shows on hover, an edit button that fades in only when hovering a card. On a touchscreen, none of that has a way to trigger. If the only way to reach a menu, a control, or information is :hover, it is functionally unreachable for anyone on a touch-only device — which today is a large share of all web traffic.

The fix isn't "never use :hover" — hover is a fine enhancement for a mouse user. The fix is: anything essential needs a way to reach it that doesn't depend on hovering — a visible button, a tap target that's always there, a focus state that also works via click or tap.

/* Fine: hover enhances an already-reachable button */
.card__action {
  opacity: 1; /* always visible and tappable */
}
.card:hover .card__action {
  transform: translateY(-2px); /* hover just adds a little polish */
}
/* Risky: this control has NO way to appear without :hover */
.card__action {
  opacity: 0;
}
.card:hover .card__action {
  opacity: 1; /* unreachable on a touchscreen */
}

Try it yourself

This example is written mobile-first: the base styles stack a navigation list vertically with generously sized tap targets, and a single min-width query switches it to a horizontal row once there's enough width. Resize a real browser window to see the switch — this embed is a fixed width.

Try it yourself
Loading playground...

What to remember

  • Mobile-first: base CSS is the small-screen layout, min-width queries add complexity as the screen grows. Desktop-first does the reverse with max-width, often undoing rules it just wrote.
  • Mobile-first tends to produce simpler CSS because it only ever adds, never fights an earlier override — and starting constrained forces real prioritization of content.
  • WCAG 2.2's target size minimum is 24×24 CSS px; 44×44 CSS px is a common, more comfortable target above that floor.
  • Touchscreens have no :hover state — anything essential must be reachable without hovering, or it's unreachable on touch devices entirely.

Check yourself

3 questions · pass 3/3 to unlock Colors and Backgrounds

up to 50
  1. 1.In mobile-first CSS, what do the unqualified (non-media-query) rules describe?

  2. 2.What is the WCAG 2.2 minimum recommended touch target size, and what's a common more comfortable target above that minimum?

  3. 3.Why is a hover-only way of revealing something a genuine accessibility problem, not just a minor inconvenience?

3 left to answer