Device mode gives you the full logical screen height. A real browser subtracts its own toolbars — typically 100–190 CSS px on a phone — and the amount changes as you scroll. Anything positioned relative to the bottom of the screen needs a real device.
| What device mode gets right | What it gets wrong |
|---|---|
| CSS viewport width — accurate, and it is the input to every media query. | Viewport height — reported as the full screen, before the browser toolbars are subtracted. |
Device pixel ratio, so srcset picks the same candidate. | Dynamic toolbars — the visible height changes as the user scrolls, and emulation never models it. |
Media query evaluation, including hover and pointer. | Font rendering — different rasteriser, different metrics, different line wraps at the edges. |
| Layout arithmetic, which is where most bugs are anyway. | Scroll performance, momentum and rubber-banding. |
| User agent string, if you set it. | Real touch targets. A cursor is precise; a thumb is 9–11 mm across. |
What the chrome actually costs
On a phone in portrait, expect roughly 100–190 CSS px of the logical height to be unavailable to your layout at any given moment, depending on browser and scroll position. That is a fifth of the screen. A "full-height" hero built against the emulated height overflows on every real handset.
This is exactly what the newer viewport units were introduced for:
| Unit | Resolves to | When to reach for it |
|---|---|---|
100vh | The large viewport — chrome hidden | Legacy. Almost never the value you want on mobile. |
100svh | The small viewport — chrome shown | Default choice. Guarantees the element fits without scrolling. |
100lvh | The large viewport, explicitly | When you deliberately want the taller measurement. |
100dvh | Dynamic — tracks the chrome live | App shells. Costs a reflow as the toolbar moves, so it can look restless on a scrolling page. |
.shell {
min-height: 100svh; /* fits with chrome shown */
padding-bottom: env(safe-area-inset-bottom, 0px); /* clears the home bar */
}
/* If you need the dynamic behaviour, opt into it explicitly */
@supports (height: 100dvh) {
.app-shell { height: 100dvh; }
}
A short checklist for real hardware
You do not need a device lab. You need one phone, one tablet and one laptop that is not the one you designed on, and you need to check these six things on them:
- Bottom-anchored UI. Sticky bars, floating buttons, toasts. This is where the height error shows up first.
- The keyboard. Focus a text input. On iOS the viewport resizes and scroll position jumps; a fixed footer will land in the middle of the screen.
- Landscape. Rotate. Side safe-area insets become non-zero, and the height collapses to something most layouts have never been tested at.
- Touch targets. 44 × 44 CSS px minimum, and check spacing between adjacent targets, not just their size.
- Text at 200%. Raise the system font size. This is a WCAG requirement and it finds every fixed-height container you have.
- Dark mode. If you ship a dark theme, look at it on an OLED panel — the contrast reads very differently from an LCD.
Where emulation is genuinely enough
Do not over-correct. Layout arithmetic, breakpoint behaviour, grid and flex reflow, image candidate selection and media query logic are all faithfully reproduced — and that is where the majority of responsive bugs live. Device mode is the right tool for the first ninety percent. It just cannot tell you how tall the screen is.
The device catalogue lists the logical viewport for 242 devices, which is the number to type into device mode's custom size field. Subtract the chrome yourself when height matters.
Questions
Is Chrome device mode accurate for responsive testing?
For width, breakpoints and layout arithmetic, yes — those are the same engine paths a real device runs. For viewport height, font rendering, scroll physics and touch, no. Use it for the first pass and verify anything height-dependent on hardware.
Why does 100vh scroll on mobile?
Because vh resolves against the viewport with the browser toolbars hidden. While they are visible, 100vh is taller than what you can see. Use 100svh instead.
What is the minimum touch target size?
44 × 44 CSS px per Apple's guidance, 48 × 48 dp per Google's. WCAG 2.2 sets 24 × 24 as a floor with spacing exceptions. Design for 44 and you satisfy all three.
Do I need to test on Safari specifically?
Yes, if you support iOS at all — every iOS browser uses WebKit regardless of its name, so Chrome on iPhone is Safari with a different interface. A Chrome-on-Android pass tells you nothing about it.