The Mobile Screenshot Was 390 Pixels Wide and Still Lied About the Viewport

A 390-pixel-wide capture showed horizontal overflow. The visual review appeared to have found a mobile layout bug.
Except it had not.
Headless Chrome had kept an approximately 500-pixel layout viewport and cropped the image to 390 pixels. The screenshot dimensions were correct. The page geometry behind them was not.
It was a perfectly measured picture of the wrong experiment (very scientific).
Two screenshots, two false readings
The first attempt used a browser extension inside a docked window. That window could not cross roughly 804 pixels, so the desktop grid breakpoint never rendered. Resizing the visible panel did not produce the layout state the review needed.
The second attempt looked more controlled:
Google\ Chrome --headless=new --window-size=390,844 --screenshot page.html
The output file was 390 pixels wide. Every mobile capture appeared to overflow horizontally.
Runtime inspection revealed the mismatch. Chrome had clamped the actual window or layout viewport to about 500 pixels and cropped the capture. CSS media queries and layout ran against one width while the screenshot was judged at another.
This is why screenshot dimensions are not viewport evidence.
Set device metrics before navigation
The working path used the Chrome DevTools Protocol (CDP) from a Node script.
The script started Chrome with a remote debugging port, connected over WebSocket, created a target, and attached to it. Before navigating, it sent Emulation.setDeviceMetricsOverride:
{
width: 390,
height: 844,
deviceScaleFactor: 2,
mobile: true,
}
The recorded working probe set the metrics before Page.navigate. No after-navigation control was run, so I treat that ordering as the verified recipe rather than a measured claim about every other ordering.
The same session then used Page.captureScreenshot with captureBeyondViewport and an explicit clip for the visual artifact.
Now the image and the runtime shared one geometry.
Ask the page what it rendered
A screenshot can show that something looks wrong. It is weak evidence about why.
The CDP probe also ran JavaScript through Runtime.evaluate and collected:
window.innerWidthand the document'sscrollWidth;- elements whose bounds exceeded the viewport;
- computed font sizes and line heights;
- line counts for wrapping-sensitive text;
- the bounding boxes of layout-critical elements.
That changed the review from “this looks overflowed” to a testable statement:
viewport width = 390
document scroll width = 390
overflow offenders = 0
In the recorded pass, the probe found no horizontal overflow. It did find other concrete issues, including a 13-pixel body font on one page and a mobile index column that wrapped.
The false alarm disappeared, and the real defects became measurable.
This was a browser-specific reader failure
I have a broader draft called “A Green Gate Only Proves What Its Reader Can See.” This incident is the browser-specific sequel: the image file reported one width while CSS layout used another.
The useful addition is not another general warning about proxies. It is a concrete pairing for responsive review: capture pixels and query runtime geometry from the same emulated target.
Keep pixels and geometry together
Visual verification works best when one controlled browser session produces both kinds of evidence:
- Emulate the target device metrics.
- Navigate after the override is active.
- Read runtime geometry and computed styles.
- Capture the screenshot from that same target.
- Store the viewport parameters beside the results.
The screenshot answers what the page looked like. The runtime probe answers what it laid out. Neither should silently borrow dimensions from a different browser state.
If a 390-pixel screenshot shows overflow, check window.innerWidth before touching the CSS. You may have found a layout bug.
Or you may have asked a 500-pixel page to pose for a 390-pixel photograph.
Get the next post.
If you made it to the end, meet the next post in your inbox or RSS reader.