RizTech Academy logo
RizTech Academy
Responsive DesignLesson 1 of 725 min

Mobile-first thinking

Mobile-first is not "design for phones". It is a claim about which CSS should be the default and which should be the exception, and once you see the argument you will not write it the other way round again.

The two ways to write the same layout

Desktop-first, using max-width:

.cards {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 2rem;
  padding: 3rem;
}

@media (max-width: 900px) {
  .cards { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; padding: 2rem; }
}

@media (max-width: 600px) {
  .cards { grid-template-columns: 1fr; gap: 1rem; padding: 1rem; }
}

Mobile-first, using min-width:

.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1rem;
  padding: 1rem;
}

@media (min-width: 600px) {
  .cards { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; padding: 2rem; }
}

@media (min-width: 900px) {
  .cards { grid-template-columns: repeat(3, 1fr); gap: 2rem; padding: 3rem; }
}

Same three layouts. Same number of lines. And the second is better for four reasons that are not about taste.

Why the second one is better

1. The default is the simplest case. One column, small padding. That is what an unknown device gets — a feature phone browser, a smartwatch, a text browser, a screen reader, an email client, a print stylesheet. When something you have never heard of renders your page, mobile-first gives it the layout that cannot go wrong.

2. You add complexity rather than undoing it. In the desktop-first version, every media query overrides something. Three columns becomes two becomes one, 3rem becomes 2rem becomes 1rem. Each rule fights the one above it, and when a bug appears you are reading three declarations to find which won. Mobile-first only ever adds.

3. The cascade is working with you. min-width queries stack: at 1000px both the 600 and the 900 query apply, in source order, so the later one refines the earlier. With max-width they also stack but in the opposite direction, which is harder to hold in your head and is why people write max-width: 900px and min-width: 601px together to stop the overlap. That combination is a symptom.

4. A phone does less work. A phone parses the base rules and can skip the unmatched min-width blocks. With max-width, the phone parses the desktop layout and both overrides. The saving is small, and the direction is right.

It is a content argument, not a screen argument

The part people miss. Starting at 360px forces a decision you would otherwise avoid: what actually matters on this page?

A kirana shop's home page at 360px fits a name, one line about what the shop is, a phone number and a Prices link. That is the page. Everything you were about to add — a carousel, a testimonials row, three feature boxes with icons — has to justify itself against that list.

Then you widen. Things get more room, and you can add the secondary material. What you do not do is start with the carousel and ask how to squeeze it onto a phone, which is how a phone ends up downloading four images it then hides with display: none.

And display: none is not responsive design. The content is still downloaded, still in the DOM, still read by search engines, and a phone user simply gets less. If something is worth hiding on mobile, ask whether it was worth having.

The Indian context makes this concrete

For an audience in Pune, most visitors arrive on a mid-range Android on mobile data. Not a design preference — an observation about who is actually looking.

Which means the base stylesheet is what almost everyone gets, and the desktop refinements are the minority case. Writing the majority case as a series of overrides to the minority case is the wrong way round.

It also means data costs money. A 2MB hero image the phone hides is real rupees spent on nothing.

Breakpoints come from the content

Do not start from device names. There is no "the iPhone width" — there are dozens, and Android is worse. A breakpoint copied from a device list is obsolete within a year.

Widen the browser slowly and stop where the layout stops looking right. That is a breakpoint. Usually you need two or three, and they land somewhere near:

@media (min-width: 40rem)  { }   /* ~640px — two columns become possible */
@media (min-width: 60rem)  { }   /* ~960px — a sidebar fits */
@media (min-width: 80rem)  { }   /* ~1280px — cap the line length */

rem rather than px in the query, deliberately. A media query in rem is measured against the browser's default font size, not your html font-size — so a visitor who has set 24px text gets your larger layout sooner, which is what they want. In px the breakpoint ignores them entirely.

Two or three is usually enough. Seven breakpoints means the layout is not really flexible; it is seven layouts.

The best breakpoint is no breakpoint

Modern CSS makes many media queries unnecessary. Before writing one, check whether one of these does the job:

/* as many columns as fit — no query at all */
grid-template-columns: repeat(auto-fit, minmax(16rem, 1fr));

/* wrap when they must */
display: flex; flex-wrap: wrap;

/* never wider than the container, never wider than 65 characters */
width: min(100%, 65ch);

/* grows with the viewport, with a floor and a ceiling */
font-size: clamp(1rem, 2.5vw, 1.5rem);
padding: clamp(1rem, 5vw, 3rem);

Each of those is responsive at every width rather than at three. The auto-fit/minmax line alone replaces most card-grid media queries, and this module covers clamp() and container queries properly in the next few lessons.

Reach for a media query when the layout needs to genuinely rearrange — a sidebar moving below the content, a navigation becoming a menu. For "make it a bit smaller", use the fluid tools.

What mobile-first is not

It is not "the mobile site". Serving different HTML to phones was a 2011 idea that produced two codebases and a permanently out-of-date one. One document, one stylesheet, adapting.

It is not "phone only". Somebody will open your kirana site on a 27-inch monitor, and an unbounded line of text 1600px wide is unreadable. Mobile-first still needs the large end designed — usually a max-width on the content container and nothing else.

It is not a rule you may never break. Occasionally max-width is genuinely clearer for one specific override. Mixing the two directions throughout a stylesheet is the problem, not using max-width once.

Check your work

What mobile-first actually claims. The simple layout is the default; complexity is added by exception.

Why the default matters. An unknown device gets the layout that cannot go wrong.

Why overrides are worse than additions. Every override is a rule fighting the one above it.

What the max-width plus min-width pair is a symptom of. Overlapping queries, which mobile-first does not have.

Why it is a content argument. 360px forces you to decide what matters.

Why display: none is not responsive design. The content is still downloaded.

Where breakpoints come from. Widening the browser until it looks wrong, not from a device list.

Why rem in a media query. It is measured against the browser's default font size, so it respects a visitor who chose larger text.

What replaces most media queries. auto-fit with minmax, flex-wrap, min(), and clamp().

When you do need a media query. When the layout must genuinely rearrange.

What mobile-first is not. A separate mobile site, phone-only, or a rule you can never break.

Practice

  1. Take the desktop-first example and rewrite it mobile-first. Count the declarations in each.
  2. Load both in devtools at 500px and use the Styles panel to count how many rules are struck through in each version.
  3. Open your own page at 360px first, with no media queries at all. List what you would cut.
  4. Find something you were going to hide on mobile with display: none. Justify keeping it or delete it.
  5. Widen a page slowly from 320px and write down every width where it stops looking right. Those are your breakpoints.
  6. Compare your list with the common device widths. Note the overlap, or lack of it.
  7. Write a breakpoint in px, then in rem. Set your browser's default font size to 24px and reload both.
  8. Replace a card-grid media query with repeat(auto-fit, minmax(16rem, 1fr)) and delete the query.
  9. Replace a font-size media query with clamp().
  10. Find a real site, open it at 360px, and decide whether it was built mobile-first. The giveaway is usually a hidden carousel or a horizontal scrollbar.

Official documentation

Next: how media queries actually work, and the ones beyond min-width.

Stuck on this lesson?

Being stuck is part of it — but being stuck alone for three days is not. Our internship programme pairs this curriculum with code review and one-to-one help from working developers, and it is free.

About the internship