---
title: "Three ways a browser shows you a page no visitor gets"
description: "Three defects on this site passed every screenshot and failed every measurement: headless Chrome refusing a phone-width layout, lazy loading that never fires inside a sideways-scrolling strip, and a scroll-driven animation that hid content permanently. A fourth, in CSS grid, pushed a footer column off the screen at phone width. All four were found by measuring, and the numbers below are from this site."
date: 2026-08-31
lang: en
canonical: https://goingstellar.ro/research/three-ways-a-browser-shows-a-page-no-visitor-gets/
author: Going Stellar
publisher: GOING STELLAR S.R.L.
topic: Measurement / front-end
license: CC BY 4.0
alternate_ro: https://goingstellar.ro/ro/cercetare/browserul-arata-trei-pagini-pe-care-vizitatorul-nu-le-vede/
---

# Three ways a browser shows you a page no visitor gets

*Three defects on this site passed every screenshot and failed every measurement: headless Chrome refusing a phone-width layout, lazy loading that never fires inside a sideways-scrolling strip, and a scroll-driven animation that hid content permanently. A fourth, in CSS grid, pushed a footer column off the screen at phone width. All four were found by measuring, and the numbers below are from this site.*

> Measurement · front-end · 2026-08-31 · https://goingstellar.ro/research/three-ways-a-browser-shows-a-page-no-visitor-gets/

## Key points

- Headless Chrome clamps the layout viewport to about 500 CSS pixels, so a screenshot taken at a 390-pixel window is a crop of a wider layout, not a phone rendering.
- Images marked loading="lazy" inside a sideways-scrolling strip can stay blank indefinitely, because a transform that moves them does not count as the image approaching the viewport.
- A scroll-driven effect may animate transform but never opacity: position may depend on scroll, existence may not.
- The reduced-motion branch of a page is a different page, not a safer version of the same one, so it has to be rendered and checked on its own.
- A global rule that hides horizontal overflow suppresses the evidence of a layout bug rather than fixing it.

## What the browser showed, and what the visitor got

We built this site and checked it the ordinary way. Open the page, take a screenshot at a few widths, look at it. That method passed three defects a visitor would have hit and a measurement caught immediately. A fourth, in the footer, was hidden by a rule we had written ourselves.

The three have the same shape. The browser renders something no visitor will ever be served. In two cases the screenshot is honest about the pixels it contains and dishonest about the layout behind them. In the third the content is not on screen at all, so there is nothing to look at and be suspicious about.

What follows is what each defect is, how it was measured, and the number the measurement returned. None of it depends on our code. The same checks run against any page.

## Headless Chrome will not render a phone-width layout

Chrome in headless mode clamps the layout viewport to about **500** CSS pixels. Ask for a window of **390** pixels and you get a **390**-pixel image of a **500**-pixel layout. It is a crop, not a rendering.

We verified it with a probe page that writes its own window.innerWidth into the document, so the value ends up in the screenshot rather than in a console we might not read. With a window size of **390**, the page printed **500**.

Two things follow. Content cut off by the crop looks exactly like a horizontal overflow bug, so you go hunting for an overflow that does not exist. And every media query below **500** pixels is never exercised at all. That is where the real phone problems live, and the tool never goes there.

The fix is device emulation over the debugging protocol, not a window size. Emulation sets the layout viewport itself, so the media queries under the clamp finally run.

## Lazy loading never fires inside a horizontally scrolling strip

A marquee is a track wider than its container, moved sideways with a transform, inside overflow: hidden. To the eye it is motion. To the browser it is a very wide element with most of itself outside the box.

An image pushed sideways out of that container never enters the viewport. A browser that honours loading="lazy" is therefore right not to load it. The images stay blank, and they stay blank indefinitely, because the transform that moves them does not count as the image approaching the viewport.

Measured on this site: **39** of **56** images in one strip never loaded. That was fixed. Later the same mistake was reintroduced in a second strip and caught again at **8** of **28**.

The second count matters more than the first. We knew the cause, had written it down, and did it again. Knowing the failure mode did not prevent it. The check did.

## Where we were wrong: the accessibility rule was the cause

A scroll-driven animation with a fill mode holds its starting state before its range begins. That is the specified behaviour and usually what you want. It becomes a defect when the range never begins: a page too short to scroll, an unusual viewport, anything where the scroll position that would start the animation is unreachable. The element then stays at its starting state forever. If that state is opacity zero, the content is simply gone.

Here is the part we got wrong. We had treated the reduced-motion branch as safer by definition: less movement, same page. It is not. A global rule that collapses every animation duration under reduced motion also collapsed the animation that was doing the positioning. A scene that distributed items across a circle stacked all of them at one point instead.

The accessibility branch was not a degraded version of the page. It was a different page, and *worse*. We saw it only because we rendered in both motion regimes rather than one. Had we checked the default regime alone, the version served to people who ask for less motion would have shipped broken.

The rule that came out of it is narrow and absolute. A scroll-driven effect may animate transform. Never opacity. Position may depend on scroll. Existence may not.

## 1fr is not a minimum of zero

In CSS grid, 1fr does not mean "as small as needed". It means minmax(auto, 1fr), and the auto minimum is the content's minimum. A single unbreakable word raises a column's minimum width, and a grid that fits everywhere else stops fitting.

One email address did exactly that to an entire footer column at phone width. It pushed the column off the screen. A body rule hiding horizontal overflow kept the page from showing a scrollbar, so the only symptom was content that was not where it should be, with no way to reach it.

The lesson is small. Treat a global overflow-hiding rule as something that suppresses evidence, not something that fixes layout.

## How to run the same checks

Check the viewport before you trust the screenshot. Load a probe page that writes window.innerWidth and the root element's client width as visible text. If the number is not the one you asked for, the screenshot is a crop, and every conclusion drawn from it is about a layout you did not request.

Check images by state, not by eye. After load and after the page has settled, count the images whose complete flag is false. Run that count inside horizontally scrolling containers specifically, because that is where it comes back non-zero while the screenshot looks full.

Compare width against width. Put the document's scroll width next to the viewport width at each breakpoint, with any overflow-hiding rule temporarily disabled. Hiding overflow does not remove the overflow. It removes the scrollbar that would have told you.

Render in both motion regimes. Once with reduced motion requested and once without, then compare the positions of the elements that animate. Where an element is settled in one regime and not the other, you have found either a defect or the two different pages you are shipping.

## Limitations

This describes browser behaviour as of August 2026. The headless clamp in particular is an implementation detail, not a standard. It may change, and the right response is to re-run the probe rather than to trust the number in this article.

The counts come from this site's markup. **39** of **56** and **8** of **28** say the failure mode exists and is detectable. They say nothing about how common it is on the web, and nothing about how many images some other strip would fail to load elsewhere.

The checks detect absence: an image that did not load, an element that did not settle, a page wider than its viewport. They do not tell you whether the layout is good, whether the copy fits, or whether a real device on a real network behaves the same. They narrow down what a person holding a phone still has to look at. They do not replace that person.

And each of these was found because someone thought to measure that particular thing. A defect nobody thought to measure is still there, and this article is not evidence otherwise.

## Questions and answers

### Why do headless Chrome screenshots at phone width look wrong?

Headless Chrome screenshots at phone width look wrong because headless Chrome clamps the layout viewport to about 500 CSS pixels. A window of 390 pixels produces a 390-pixel crop of a 500-pixel layout. The crop resembles a horizontal overflow bug that does not exist, and media queries below 500 pixels never run. Device emulation over the debugging protocol sets the layout viewport itself, so those media queries finally run.

### Why do lazy-loaded images stay blank inside a marquee or horizontal strip?

Lazy-loaded images stay blank inside a marquee because the track is moved sideways with a transform inside overflow: hidden, so images pushed outside the container never enter the viewport. A browser that honours loading="lazy" is right not to load them. On one site, 39 of 56 images in a strip never loaded. Counting images whose complete flag is false, inside horizontally scrolling containers specifically, catches the problem.

### Can a scroll-driven animation hide content permanently?

A scroll-driven animation can hide content permanently when it uses a fill mode and its range never begins. The animation holds its starting state before the range starts, so on a page too short to scroll, or an unusual viewport, the element stays in that state forever. If the starting state is opacity zero, the content is gone. The safe rule is to animate transform with scroll, never opacity.

### Is the reduced-motion version of a page automatically safer?

The reduced-motion version of a page is not automatically safer. A global rule that collapses every animation duration under reduced motion can also collapse an animation that positions elements: in one case, a scene that distributed items across a circle stacked them all at one point. Rendering the page once with reduced motion and once without, then comparing element positions, is the way to see the difference.

### Why does a CSS grid column set to 1fr overflow on a phone?

A CSS grid column set to 1fr can overflow on a phone because 1fr means minmax(auto, 1fr), and the auto minimum is the content's minimum width. A single unbreakable word, such as an email address, raises that minimum, so a grid that fits elsewhere stops fitting. A body rule hiding horizontal overflow then removes the scrollbar, leaving content off screen with no way to reach it.

### How can I test a web page for defects that screenshots miss?

Testing a web page for defects that screenshots miss means measuring rather than looking. Load a probe page that prints window.innerWidth to confirm the viewport, count images whose complete flag is false, compare the document's scroll width with the viewport width while overflow hiding is disabled, and render in both motion regimes. These checks detect absence; they do not replace a person checking on a real phone.

## How to cite

**Cite this as:** Going Stellar (2026). *Three ways a browser shows you a page no visitor gets*. GOING STELLAR S.R.L.. https://goingstellar.ro/research/three-ways-a-browser-shows-a-page-no-visitor-gets/

```bibtex
@misc{goingstellar2026three,
  title  = {Three ways a browser shows you a page no visitor gets},
  author = {{Going Stellar}},
  year   = {2026},
  url    = {https://goingstellar.ro/research/three-ways-a-browser-shows-a-page-no-visitor-gets/},
  note   = {2026-08-31}
}
```

Licence. Free to quote with attribution.

## Also available

- This page as HTML: https://goingstellar.ro/research/three-ways-a-browser-shows-a-page-no-visitor-gets/
- Same article in Romanian: https://goingstellar.ro/ro/cercetare/browserul-arata-trei-pagini-pe-care-vizitatorul-nu-le-vede/
