Note
The one line that decides how a phone renders a page
A missing viewport meta tag does not break a page. It does something worse: the phone lays it out at a desktop width and shrinks the result to fit the glass, so a perfectly good responsive stylesheet never matches a single media query.
- Mobile
- Front end
- CSS
What a phone does without it
A mobile browser has two viewports. The visual viewport is the glass. The layout viewport is the width CSS believes it has, and by default the two are not the same thing: faced with a page that says nothing about its own width, a phone assumes it was written for a desktop, lays it out at a fallback width of roughly a thousand CSS pixels, and then scales the whole rendered result down to fit the screen.
The result is the one everybody recognises: a complete, correct desktop layout rendered at about a third of legible size, with pinch-zoom as the only way to read it. Nothing has failed, so nothing is reported.
The second effect is the expensive one. Media queries resolve against the layout
viewport, so a min-width breakpoint matches on a phone whose screen is
nowhere near it. A responsive stylesheet tested at every breakpoint on a laptop does
exactly nothing on the device it was written for, and the defect is one missing line
rather than anything in the CSS.
The line
<meta name="viewport" content="width=device-width, initial-scale=1">
Two instructions. width=device-width sets the layout viewport to the
device's own width in CSS pixels, so layout happens at the size the page is being read at
and media queries start telling the truth. initial-scale=1 sets the opening
zoom to one, so the browser does not helpfully scale the result after being told the
right width.
It belongs in the head of every page rather than in one template, and on a
site built from a single layout it is one edit. That is the whole fix.
What not to add
user-scalable=no, andmaximum-scale=1. They take away a reader's ability to zoom. The resize-text criterion in WCAG exists for people who need text larger than you chose for them, and removing pinch-zoom is an accessibility failure with no corresponding benefit. Mobile Safari has ignoreduser-scalable=nofor years precisely because it was abused this way, so the line is both wrong and ineffective.- A fixed
width=1024. That is the original problem, written down deliberately. viewport-fit=cover, unless something needs it. It lets the page draw into the rounded corners and the notch area of a device, and once you have asked for that, keeping content out of those regions with theenv(safe-area-inset-*)values is yours to do. Worth it for an edge-to-edge header; not worth it by default.
When the line is there and it is still wrong
One element wider than the viewport — a fixed-width table, an oversized image, a preformatted block that will not wrap, a hardcoded pixel width in an inline style — gives the whole document horizontal scroll, and on a phone that reads as a broken layout rather than as one wide table. Find the offender in the console rather than by inspection:
Array.from(document.querySelectorAll('*'))
.filter(el => el.getBoundingClientRect().right > window.innerWidth + 1)
.slice(0, 20)
Then fix it in CSS rather than by removing the viewport line, which is the shortcut that trades one wide element for every phone layout on the site.
Why this is the cheapest item on the list
No build change, no dependency, no deploy risk: one line in the head. It is also the only defect of its kind that every visitor on a phone experiences immediately and silently. They do not report it, they leave. Of everything measurable about a site from outside, this is the shortest distance between a measurement and a fix.
Sources
Where this is written down
- CSS Viewport Module Level 1, CSS WG editor's draft — the viewport meta tag is specified as a translation into viewport descriptors, which is where width=device-width and initial-scale are actually defined
- Web Content Accessibility Guidelines 2.2, W3C editor's draft — the resize-text success criterion is the reason a page may not take zoom away from a reader who needs the text larger than the author chose
Related
Where this comes up in the work
Web, apps & DevOps
Web and app builds with the DevOps around them: front end, backend, the database under it, and the build, deploy and monitoring work that keeps it up.
More notes
Other things worth writing down
What a PX page actually weighs, and the switch that halves it
A PX view ships about 2.3 MB of framework JavaScript before your graphic. Gzip is off by default, and /module/* bypasses the filter that would do it.
- PX graphics
- JACE
- Performance
A link check that runs before a visitor finds the 404
A link check over your own built output, in CI: the four classes of break it finds, and why it works locally and it worked last deploy both miss them.
- Deployment
- Front end
- Testing
What a browser does with http assets on an https page
A stylesheet or script fetched over http on an https page is blocked outright. What a browser does with each kind, and how to find every one in your HTML.
- https
- Browsers
- Front end
Next step
Tell us the version, the hardware, and what it has to do.
You will get a written scope and a fixed price against it. If the honest answer is that you do not need us, you will get that instead.