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.
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#555Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Screen & display
- the outer window fits within the screen
window-boundsThe check asserts only the zoom-invariant bound: window.outerWidth/outerHeight must be non-zero and must fit within the screen. - a non-touch desktop has a fine pointer + hover
pointer-hover-desktopThis check applies only when the UA identifies a desktop platform (Windows, Macintosh, Mac OS X, X11, Linux, CrOS, and not Android/Mobile)… - maxTouchPoints coheres with pointer media
touch-pointer-coherenceA one-directional coherence test: if navigator.maxTouchPoints is greater than zero, matchMedia("(any-pointer: coarse)") is expected to… - screen dimensions resolve via native prototype getters
screen-descriptorsFor width, height, availWidth, availHeight, colorDepth and pixelDepth this asks two questions: does the screen instance carry an own… - screen.orientation agrees with the screen's own dimensions
orientation-vs-screen-dimsscreen.orientation.type and screen.width/height are both device-space values sourced from the same display metrics, so they must agree: a… - a mobile UA has a real touch stack
touch-createevent-coherenceThis check asserts in one direction only: if navigator.userAgent matches iPhone, iPad, iPod or Android, then the environment must also have… - visualViewport agrees with innerWidth/innerHeight
visual-viewport-vs-windowwindow.innerWidth and visualViewport.width are two independent readings of one viewport, and they are related by exactly one thing: the… - navigation timing milestones run in their spec-defined causal order
nav-timing-orderAkamai Bot Manager v2 devotes an entire signal category to timing — navigation timing, resource timing, first paint, DOM-ready — and this…
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.