How to test responsive design
Most responsive testing checks a list of phone names and misses the bugs entirely. The breakpoints that matter are the ones your own CSS declares — and four classes of bug never show up in device mode at all.
Read the @media queries the page declares and test one pixel either side of each one, plus 320px and your widest supported width. Then check the four things emulation cannot reproduce: dynamic viewport height, sticky hover on touch, font fallback, and which image the device pixel ratio picks.
1. Find the real breakpoints
Testing "iPhone 15, iPad, Desktop" tests three arbitrary widths. Your layout does not change at those widths — it changes at the widths written in your stylesheet. Test those and you cover every device that will ever exist; test device names and you cover three of them.
Three ways to get the list:
DevTools media query bars
Open device mode, then the three-dot menu on the toolbar → Show media queries. Coloured bars appear above the ruler, one per query in the page's CSS. Click any bar to jump straight to that width.
Search the stylesheet
In the Sources panel, open the CSS file and search for @media. Slower, but it also shows you what each query changes, which the bars do not.
Ask the element
An inspector that reports breakpoints gives you only the queries affecting the element under your cursor — usually what you want, because a large site has dozens of queries and two of them concern the component you are debugging. Design Toolkit lists them with the values at each, including @container queries, which no media query bar will ever show you.
2. Test either side of each one
Bugs live at the boundary. A grid that goes from three columns to one at 768px is fine at 900px and fine at 600px; the interesting widths are 767px and 768px, where a heading might suddenly wrap or a card might get 12px too narrow for its content.
So for each breakpoint, look at it twice — just below, just above. This is where a side-by-side viewer earns its place: both states on screen together, rather than resizing back and forth trying to remember what the last one looked like.
3. Check the two extremes
- 320px. Still the sensible floor. Anything narrower is rare enough to ignore; anything wider hides the overflow bugs that 320px exposes. Watch for long unbroken strings — URLs, email addresses, product codes — which force horizontal scroll on the whole page.
- Your widest. If your container has no
max-width, check an ultrawide monitor: line lengths of 200 characters, and heroes where the text and the image drift apart.
A fast way to find overflow at any width: in the console, list anything wider than the viewport.
document.querySelectorAll('*').forEach(el => {
if (el.getBoundingClientRect().right > document.documentElement.clientWidth)
console.log(el);
});
4. The four bugs emulation cannot show you
Dynamic viewport height
On a phone, the address bar hides as you scroll, so the visible height changes while 100vh does not. A full-height hero is cut off at first load and leaves a gap once the bar hides. Use 100dvh, with 100vh before it as the fallback.
Sticky hover
There is no pointer to move away on a touch screen, so a tapped element keeps its hover state until something else is tapped. Cards that lift on hover stay lifted; buttons stay highlighted. The fix is to make hover styles conditional:
@media (hover: hover) {
.card:hover { transform: translateY(-4px); }
}
Font fallback
A typeface installed on your machine renders locally and falls back on a device that does not have it — with different metrics, so a heading that fit on one line now takes two. Test with local fonts disabled, or check on hardware. If you rely on a system font stack, know what each platform will actually pick.
Which image gets chosen
A phone at a device pixel ratio of 3 requests a much larger file from your srcset than your desktop does. Set the DPR in device mode and watch the Network panel to confirm the right file is being served, not the 2400px one over a mobile connection.
The checklist
- Every declared breakpoint, one pixel either side
- 320px, with no horizontal scroll anywhere
- Your widest supported width
- Tap targets at least 44×44px, with space between them
- Hover styles behind
@media (hover: hover) dvhinstead ofvhfor full-height sections- Tables and code blocks scrolling inside their own container, not the page
- Text still passing contrast over any image that reflows
- One pass on a real phone, throttled to a slow connection
Read the breakpoints instead of hunting for them
Hover an element for the media and container queries that apply to it, and what each changes — plus the spacing and type at every width. Free for 7 days.
Add to Chrome — free trialCommon questions
What screen sizes should I test?
Your own breakpoints, not a list of device names. Read the media queries in your CSS, test one pixel either side of each, and add 320px plus your widest supported width.
Is resizing the browser window enough?
It catches layout breaks, which is most of them. It misses touch behaviour, the address bar changing viewport height, font fallback, and which image a device pixel ratio selects.
Why does 100vh break on mobile?
The address bar hides as you scroll, so the visible height changes while 100vh does not. Use 100dvh and keep 100vh as a fallback.
How do I stop hover styles sticking on touch?
Wrap them in @media (hover: hover). Without a pointer, a tapped element keeps its hover state; the query stops those styles applying at all.