Skip to content
All fingerprint checksScreen & display

the CSS layout viewport width equals window.innerWidth

Check id css-viewport-vs-innerwidth-coherence

What an ordinary browser yields

The largest matching (min-width: Npx) breakpoint equals window.innerWidth within the measured scrollbar gutter — one layout viewport feeds both, so on a real browser the gap is a scrollbar at most.

What a detector infers

window.innerWidth and the width CSS media queries evaluate against are the same quantity read two ways. matchMedia("(min-width: Npx)") is answered by the layout engine from the CSS viewport, while innerWidth is a JavaScript property; in a real browser the largest N that still matches is innerWidth, give or take the scrollbar gutter, because both are computed from one layout viewport. A spoof that rewrites innerWidth to a persona value leaves the CSS engine laying out at the real width, so the two decouple — not by a rounding pixel but by hundreds. That decoupling is not hypothetical: it is the shape that made Akamai block a Firefox-based anti-detect browser while passing stock Firefox on the same machine, because the browser reported a spoofed innerWidth its own layout engine never honoured. The gutter is measured with a private probe element rather than derived from innerWidth minus clientWidth, since a rewritten innerWidth would move both sides of that subtraction together and cancel itself out; a probe div is independent of innerWidth, so a rewrite still shows. The check declines on any unstable basis — a zero or absent innerWidth, a document not yet settled, a hidden or backgrounded tab, or a pinch-zoomed visual viewport — and it is scored warn rather than critical because a legitimate scrollbar gutter means the two are near-equal rather than spec-identical.

How to resolve it

innerWidth and the width CSS media queries lay out against are one layout viewport read twice, so they cannot decouple by more than a scrollbar in a real browser. Resize the actual window rather than rewriting innerWidth — the layout engine keeps measuring the true surface, and the disagreement it creates is louder than the value you were trying to present.

How is a headless browser detected?

Read in the wild by

Camoufox issues

The tracker records the browser reporting a spoofed innerWidth decoupled from its real CSS layout viewport, which a named commercial detector blocked while stock Firefox on the same box passed.

daijro/camoufox #555, #554 (innerWidth vs layout viewport; Akamai block)

daijro/camoufox#555

Every attribution traces to a published artifact. See the sources and their limits.

Nearby checks in Screen & display

See all 15 checks in Screen & display
Who builds this test

Clearcote is a browser built for fingerprint coherence

It is a Chromium fork, maintained by the same people who wrote this reference. It ships as a compiled browser rather than as a stealth script injected into someone else's — which is a description of how it is built, and is not an argument about how it behaves on this check.

This audit takes no position on how Clearcote scores on Screen & display checks, on this one, or anywhere else. It has no baseline corpus of other people's fingerprints to rank you against and no vendor scoreboard — nearly every check is self-referential, asking one browser the same question through two independent APIs and reporting whether both answers can be true at once. It runs identically on any browser, including ours. Run it on yours and read the result yourself.

See the other checks in Screen & display — the family css-viewport-vs-innerwidth-coherence belongs to.