Mobile / touch · M.2
Shrink-to-fit zoom guard
A sofa that will not fit through the door, so the removal men shrink the house.
When a layout's min-content width exceeds the device width, a mobile browser zooms the whole page out to make it fit, and every word on it gets smaller.
4 knobs
How it actually works
This is the single most valuable page in this category because the defect is invisible unless you know to look for it. There is no sideways scrollbar. Nothing overflows. The page simply renders small, and it renders small UNIFORMLY, so it reads as a design choice rather than as a bug. Our own audit harness reported a page with a 495px layout on a 390px screen as a clean PASS until the check was rewritten to compare against the width we asked for rather than the width the browser reported back, because window.innerWidth inflates along with the zoom and the comparison cancelled itself out.
A mobile browser lays the page out at a layout viewport of max(device width, the page's min-content floor), then scales the result down by device width / layout width so it fits the screen. One 495px element on a 390px phone therefore renders the ENTIRE page at 79%, not just that element. The floor is set by whatever refuses to get narrower: a fixed px width, a white-space: nowrap run, a long unbroken word, a table row, or a clamp() whose floor is wider than the box it lives in. The fixes are all about giving that thing somewhere to go: overflow-wrap: break-word, a fluid max-width: 100%, or a smaller clamp floor below the width where it stops fitting.
The knobs, named
Offending width, unbreakable run, the fix, and the device width you are testing at. Only the fix knob is sourced, because overflow-wrap and max-width are named CSS properties; the other three are our instrumentation of the defect.
| Knob | Source | What it teaches |
|---|---|---|
| Offending width | ours | A block with a hard px width, the commonest cause. Push it past the device width and watch the zoom percentage fall and every word on the page shrink with it. |
| Unbreakable run | ours | The other cause, and the one that arrives later: a client pastes a street name or a URL into copy that was fine on launch day. A nowrap run cannot be narrowed at all. |
| The fix | sourced | overflow-wrap breaks the unbreakable run; a fluid max-width dissolves the fixed block. Each fixes one cause only, which is why the honest answer on a real page is usually both. |
| Device width | ours | The screen you are testing on. 320 is the narrowest phone still in real use and it is the width that exposes this; 390 is a modern iPhone. A layout can pass at 414 and shrink at 320. |
sourced means the source names this parameter. ours means the source names none and the knob is our design against the mechanism. No knob here is invented and passed off as sourced.
Evidence
VERIFIED (ours, shipped)
Our own shipped code and our own instrument. The fix: clients/harrison-handyman/craft.css section 3, "THE DISPLAY HEAD AT NARROW WIDTHS". h1 at clamp(2.5rem, 7vw, 4.6rem) held a 40px floor below ~357px, the word set 330px wide in a 272px box, and Chrome shrink-to-fit-zoomed the whole site to ~90%: measured 354px of layout on a 320px screen (index) and 349px (woodworking). Fixed with a narrower clamp below 400px plus overflow-wrap: break-word below 760px. The instrument: kit/mobile-audit.cjs, whose SHRINK-TO-FIT check and its comment record a 495px layout on a 390px phone reported as PASS before the comparison was moved onto the requested width. No third-party source is cited because none was consulted.
- Seen on
- tabblabs.net and the harrison-handyman build, both ours, both measured 2026-07-21.
- Dependencies
- vanilla CSS
- Difficulty
- trivial to fix, genuinely hard to notice
- Performance
- No runtime cost at all. It is a layout constraint, not an effect.
- Accessibility and the floor
- This IS an accessibility defect, not a cosmetic one: a page rendered at 79% puts body copy near 12px and pushes every target under the size floor at once. The zoom is applied on top of whatever the reader already set, so it compounds with their own font-size preference rather than respecting it.
Notes
Composability. It is a constraint on everything else, not a thing you add. Any feature on this site that declares a px width inside a phone-width container can cause it, which is why the guard belongs in the base stylesheet rather than in a component.