mobile first approach: stop building for your monitor
2025-08-15·6 min read
Open any AI-generated landing page on your phone. There's a good chance something is broken — text overflowing, buttons too small to tap, a layout that's clearly designed for a widescreen and squished into a 390px viewport.
This happens because most people build on a laptop or desktop, eyeball it in the browser, and assume it's done. The phone is an afterthought. Sometimes it's not even checked.
Mobile first flips that. You design and build for the smallest screen first, then scale up. It sounds simple. Most people don't actually do it.
why desktop-first breaks
When you write CSS without thinking about screen size, you're implicitly writing for whatever screen you're looking at. A width: 800px container looks fine on your monitor. On a 390px phone screen it either overflows, gets clipped, or forces a horizontal scroll.
The instinct to fix this is to add media queries that shrink things down for mobile:
/* desktop-first — you're fighting the small screen */
.container {
width: 800px;
display: flex;
gap: 24px;
}
@media (max-width: 768px) {
.container {
width: 100%;
flex-direction: column;
}
}This works but it's the wrong direction. You're writing the complex layout first and then trying to undo it for mobile. The mobile styles become a pile of overrides. The more components you have, the messier it gets.
mobile first means min-width, not max-width
Mobile first means your base styles are for the smallest screen. Media queries add complexity as the screen gets larger — not the other way around.
/* mobile first — you're adding to the small screen */
.container {
width: 100%;
display: flex;
flex-direction: column;
gap: 16px;
}
@media (min-width: 768px) {
.container {
flex-direction: row;
gap: 24px;
}
}
@media (min-width: 1280px) {
.container {
max-width: 1200px;
margin: 0 auto;
}
}Base styles handle mobile. The min-width breakpoints progressively add the wider layout. Each breakpoint builds on the previous one instead of undoing it.
The difference sounds minor. At scale it isn't. Desktop-first accumulates overrides. Mobile first accumulates additions. Additions are easier to reason about.
flexbox is your main tool here
Flexbox and mobile first work well together because flexbox is inherently flexible — it distributes space based on available width, not fixed values.
The pattern you'll use constantly:
/* stack vertically on mobile */
.card-grid {
display: flex;
flex-direction: column;
gap: 16px;
}
/* side by side on tablet */
@media (min-width: 768px) {
.card-grid {
flex-direction: row;
flex-wrap: wrap;
}
.card-grid > * {
flex: 1 1 calc(50% - 8px);
}
}
/* three columns on desktop */
@media (min-width: 1024px) {
.card-grid > * {
flex: 1 1 calc(33.33% - 11px);
}
}Mobile: single column stack. Tablet: two columns. Desktop: three columns. Each breakpoint adds one rule, not a full reset.
flex: 1 1 calc(50% - 8px) means: grow, shrink, base width of 50% minus half the gap. That's the pattern for equal-width flex children that wrap correctly.
[screenshot: same card grid at 390px, 768px, and 1280px viewport widths]
how to actually build this way
Start in DevTools mobile view. Before writing a single line of CSS, open DevTools (F12), click the device toolbar icon, and set it to a phone viewport — 390px is iPhone 14, 360px covers most Android. Build there first.
[screenshot: Chrome DevTools device toolbar with 390px selected]
Use relative units, not fixed widths. width: 100% instead of width: 400px. padding: 1rem instead of padding: 16px (same thing, but rem scales with user font settings). Avoid fixed pixel widths on containers entirely unless you have a specific reason.
Check your tap targets. Buttons and links need to be at least 44x44px to be reliably tappable on mobile. A font-size: 12px link that looks fine on desktop is nearly untappable on a phone.
/* minimum tap target */
.button {
min-height: 44px;
min-width: 44px;
padding: 12px 24px;
}Test on actual breakpoints, not just your screen size. Common ones worth checking:
| breakpoint | what it covers | |------------|---------------| | 360px | small Android phones | | 390px | iPhone 14/15 | | 768px | tablets, large phones landscape | | 1024px | small laptops | | 1280px | standard desktop | | 1440px | large monitors |
The gap between 768px and 1024px catches a lot of things that look fine on phone and fine on desktop but break in between — landscape tablets, small laptops, browser windows that aren't maximized.
the two-monitor problem
If something looks fine on your 1440p monitor but breaks on a colleague's 1280px laptop, it's usually one of these:
- a fixed-width container that fits 1440 but overflows at 1280
- a font size that looks right at 1440 but is too large at 1280
- a flex row that fits four items at 1440 but wraps badly at 1280
The fix is always the same: resize your browser window while developing, not just after. Drag the window narrower as you build. Watch where things break. That's where your breakpoint goes.
/* this breaks at smaller desktop widths */
.hero {
display: flex;
gap: 48px;
}
.hero-text {
width: 600px; /* fixed width — breaks when viewport is narrow */
}
/* this doesn't */
.hero-text {
flex: 1; /* takes available space, doesn't overflow */
min-width: 0; /* prevents flex overflow with long text */
}min-width: 0 on flex children is one of those CSS things that seems unnecessary until you hit the bug it prevents — long text or wide content inside a flex child ignoring the parent's width constraint.
debugging responsive issues
When something looks wrong on mobile:
- Open DevTools, switch to device toolbar, set to the viewport size where it breaks
- Click the element, check the computed styles — look for fixed widths, overflow values, or flex properties that aren't doing what you expect
- Check if a parent container has
overflow: hiddencutting things off - Check if the issue is the element itself or a parent
The most common culprits: fixed pixel widths on containers, images without max-width: 100%, flex children that don't shrink because flex-shrink: 0 is set somewhere, and horizontal overflow caused by an element wider than the viewport with no overflow-x: hidden on the body.
/* add this to catch horizontal overflow issues */
* {
box-sizing: border-box;
}
img {
max-width: 100%;
height: auto;
}
body {
overflow-x: hidden;
}These three rules fix a large percentage of basic mobile layout issues before you've written anything else.
Mobile first isn't a philosophy, it's a habit. Start at 390px, use min-width media queries, test at real breakpoints as you build. The apps that look broken on phones weren't built by people who couldn't do better — they were built by people who checked their work on the wrong screen.