Skip to content

Test your website now

Free, no card. We read only public pages.

Run free audit →

Mobile

Mobile usability, and the five things that actually break it

Viewport, tap targets, responsive images and mobile paint time: what breaks a site on a phone, how to test it honestly, and why desktop numbers hide all of it.

Published

Why your desktop numbers hide all of this

Most sites are built on a fast machine, on a wide screen, on an office connection, by someone who knows where everything is. Most visits are none of those things. Every measurement below diverges from the desktop equivalent, and in every case the mobile number is the one that is ranked and the one a customer experiences.

So the first change is not a fix, it is a habit: measure at a phone viewport, on a throttled connection, with a slower CPU, before deciding anything is fine. A browser's device emulation is enough to catch most of it and takes ten seconds to turn on.

Emulation is not a phone. It gets you the viewport, the touch model and a CPU multiplier, which is most of the value. It does not get you the real network, the real thermal throttling, or the browser your customers actually use. Keep one cheap real device for the things emulation cannot show you.

1. The viewport tag, and the one attribute that must not be there

Without a viewport meta tag a mobile browser assumes a desktop-width page and scales it down, which is how a site ends up rendered at 980 pixels wide on a 390-pixel screen. One line fixes it and it is the same line on every site:

<meta name="viewport" content="width=device-width, initial-scale=1">

What must not be in it is anything that stops the user zooming. `maximum-scale=1` and `user-scalable=no` both do, and both break the page for anyone who needs to magnify text - which is a great many more people than the number who find pinch-zoom annoying.

This is the cheapest accessibility failure there is: one attribute, added years ago to stop an iOS tap-zoom quirk that no longer exists, still shipping on a surprising number of sites and failing WCAG 1.4.4 outright.

2. Tap targets - and how we failed this one ourselves

WCAG 2.2 added success criterion 2.5.8: interactive targets should be at least 24 by 24 CSS pixels. It is an AA criterion, it is new enough that a lot of sites have never been measured against it, and it is almost always failed by the same two things: footer links and icon-only buttons.

The honest example is this site. Auditing our own pages with our own engine found 27 targets per page under the minimum. They were the footer links, at 350 by 22 pixels - full width, and two pixels short. The fix was two pixels of vertical padding and a matching reduction in the column gap, so nothing moved visually and every link cleared the bar.

The part worth taking away: our automated accessibility gate, running the full WCAG 2.2 rule set, passed every page before and after. axe ships its target-size rule as experimental and does not run it in that set. A criterion can be in the standard, in your rule set's name, and still not be tested by the tool you trust to test it.

How to check yours, without any tooling beyond a browser console - open the page at a phone viewport and ask the DOM directly:

[...document.querySelectorAll('a, button, input, [role=button]')]
  .map(el => ({ el, r: el.getBoundingClientRect() }))
  .filter(({ r }) => r.width && r.height && (r.width < 24 || r.height < 24))

The criterion excepts targets inside a sentence of text, so an inline link in a paragraph is not a failure. A navigation list, a footer column and a row of icon buttons are not sentences.

3. Images sized for a screen nobody is using

The most expensive mobile mistake is sending a desktop image to a phone. A 2400-pixel-wide hero downloaded over a mobile connection to be displayed at 390 pixels is not a slow image, it is four or five times more bytes than the page needed, on the connection least able to afford them.

  • Serve several sizes and let the browser pick, with srcset and a sizes attribute that describes the real layout rather than guessing 100vw everywhere.
  • Use a modern format, with a fallback for anything that needs one. This alone is usually the single largest byte saving available on a content site.
  • Set width and height, or an aspect ratio, so the space is reserved before the file arrives - otherwise every image is also a layout shift.
  • Lazy-load everything below the fold, and nothing above it. The image the metric is measuring must never be lazy.

4. Paint time, measured at the viewport that counts

Largest Contentful Paint under 2.5 seconds is the threshold, and it is measured on mobile for ranking purposes. A site comfortably inside it on desktop can be well over four seconds on a phone, and the reasons are usually the same three: a bigger image than the screen needs, JavaScript that has to run before anything paints, and a server that was already slow before any of it started.

Diagnose it in that order. If time to first byte alone is most of the budget, nothing you do to the image will help. If the largest element is discovered late - referenced from a stylesheet, injected by a script, or lazily loaded - the fix is discovery, not compression. Only then is it the file itself.

5. The small things that get noticed anyway

  • Text that reflows at 200% and 400% zoom without a horizontal scrollbar. This is a WCAG requirement and it is where fixed-width containers go to be found out.
  • Form inputs with the right type and autocomplete, so the phone offers the right keyboard and the browser can fill the field. A numeric field that opens a full alphabetic keyboard is a small insult repeated on every order.
  • A touch icon, so a page saved to a home screen is not a blurry screenshot.
  • Anything hidden behind a hover state. There is no hover on a phone; if it only appears on hover, on a phone it does not appear.
  • Fixed banners and cookie notices that eat a third of a small screen and cannot be dismissed with one thumb.

None of these five sections needs a redesign. Together they are usually a day of work, and they are the difference between a site that technically loads on a phone and one somebody can use on a train.

In the product

The checks this maps to

Every check named here runs on every scan, on every plan - what a plan changes is how many pages are crawled, how long the history is kept and what you can do with the result. These are the ids the findings carry, so you can match a line in a report to the explanation above.

  • mobile.viewport.present - Viewport meta tag present
  • mobile.viewport.config - Viewport uses device-width
  • mobile.tap-targets - Tap targets are large enough
  • mobile.responsive-images - Responsive images in use
  • mobile.touch-icon - Apple touch icon configured
  • perf.mobile.lcp - Mobile LCP under 2.5 s
  • a11y.viewport-zoom - Zoom not disabled