What a pixel is, and how wide phones actually are
A CSS pixel is not a physical thing
This trips up nearly everybody once. A CSS pixel is a reference unit defined by the angle it subtends at a typical viewing distance, not by a fixed physical size. The specification's nominal value is 1/96 of an inch at arm's length, which is about 0.26 millimetres — but that is the value for a screen viewed at roughly 60 centimetres.
On a phone held 30 centimetres away, the browser's CSS pixel is physically smaller. An iPhone 15 reports 393 CSS pixels across a screen about 71 millimetres wide, so one CSS pixel is about 0.18 millimetres there. The 44-pixel touch target from the spacing block is therefore about 8 millimetres of glass, not 11.
This is intentional rather than broken. What matters for perception is angular size — how much of your visual field something occupies — and a phone held closer needs fewer millimetres for the same angle. It does mean that reasoning about pixels as physical distances is unreliable, and that anything with a genuinely physical requirement, such as a touch target, should be checked on a device rather than on a ruler.
Device pixel ratio
The hardware has more pixels than the CSS layer admits to. Device pixel ratio is the multiplier:
iPhone 15 393 CSS px wide, DPR 3 → 1179 hardware px
budget Android 360 CSS px wide, DPR 2 → 720 hardware px
1080p laptop 1536 CSS px wide, DPR 1.25 (Windows at 125% scaling)
MacBook Pro 1512 CSS px wide, DPR 2Two consequences that decide real work:
Raster assets need to be exported at 2x or 3x. A logo displayed at 120 CSS pixels wide needs a 360-pixel file to look sharp on a DPR-3 phone. An image exported at 1x looks soft on almost every modern device.
Vector assets do not. An SVG logo or icon is resolution-independent and sharp at any ratio, at a fraction of the file size. This is the single strongest argument for drawing interface graphics as vectors, and Inkscape does it free.
The widths to design at
Mobile viewport widths cluster tightly. 360 and 390 to 393 CSS pixels cover the overwhelming majority of phones in use, and 360 is the safe floor — it is what a great many Android devices in India, Africa and Latin America report.
Design at 360. If it works there it works at 393. The reverse is not reliable: a layout that fits at 393 can break at 360, and the break is usually a fixed-width element or a long unbreakable string.
On desktop the common widths are far more spread out, and the useful number is not the screen width but the content width, which you are choosing anyway — the measure rule from the type block caps a text column at roughly 30 to 34em regardless of how wide the monitor is.
The 100vh problem
A specific, extremely common bug. height: 100vh on a mobile browser refers to the viewport height with the browser's address bar hidden. While the bar is showing — which is most of the time — the visible area is smaller, so the bottom of a supposedly full-height section is cut off, taking the button with it.
The modern units solve it:
.hero { min-height: 100svh; } /* smallest: bars showing */
.hero { min-height: 100lvh; } /* largest: bars hidden */
.hero { min-height: 100dvh; } /* dynamic: changes as bars move */svh is the safe default for anything that must be fully visible. dvh is correct for a full-screen overlay but causes the layout to resize as the user scrolls, which can look unsettled.
Safe areas
Phones have rounded corners, camera cut-outs and a home indicator bar. The operating system exposes the insets, and a layout that ignores them puts content under the notch or under the swipe bar:
.footer-bar {
padding-bottom: max(16px, env(safe-area-inset-bottom));
}The max() means you get your normal padding on devices with no inset and the correct clearance on devices with one.
Testing honestly
Browser device emulation is good for layout and useless for two things it appears to test: touch accuracy, and how anything looks in real light. Both need the actual device.
The cheapest useful test rig is one inexpensive Android phone, bought second-hand, kept on the desk, and used outdoors. It will find contrast failures, target failures and performance problems that no emulator reports, because emulation runs on your fast machine in your dim room with your mouse.
The one thing to keep
A CSS pixel is an angular reference rather than a physical size, device pixel ratio means raster assets need 2x or 3x export while vectors need none, and 360 CSS pixels is the width to design at because a layout that fits at 393 can still break there.
Before you move on
A full-screen section is set to height: 100vh with a button at its bottom edge. On desktop it is fine; on phones the button is often cut off. What is the mechanism?
Pick the one you would defend. Nobody sees your answer.