screen dimensions resolve via native prototype getters
Check id screen-descriptors
What an ordinary browser yields
width/height/avail*/colorDepth/pixelDepth are all native Screen.prototype getters, with no own descriptors on screen and no window-geometry properties present.
What a detector infers
For width, height, availWidth, availHeight, colorDepth and pixelDepth this asks two questions: does the screen instance carry an own descriptor (real browsers expose these only via Screen.prototype), and is the Screen.prototype entry still a native getter rather than a data property or a JS function. It also checks four tripwire names — innerWidth, innerHeight, outerWidth, outerHeight — which belong to Window and never to Screen; their presence on screen indicates a catch-all Proxy or a spoof mirroring window geometry onto the screen object. The reason this is severity 'critical' is that Object.defineProperty(screen,'width',{get:…}) is the most common patch there is, and it never changes a value's plausibility, so every value-coherence check still passes while the mechanism is plainly visible in the descriptor. One calibration note: the getter's native-code formatting is held to byte-exact equality on V8 only — descriptor placement and the tripwires are engine-neutral, but native stringification formatting is not, and genuine Firefox and Safari failed the exact test 100% in the corpus. Off V8 the getter is held to the loose [native code] marker instead.
How to resolve it
Spoof the screen at the engine level rather than via Object.defineProperty on the screen instance, which leaves both an own descriptor and a JS getter behind. Note that this check inspects mechanism, not values: leaving the real screen values in place passes it outright, which is often the simplest option.
Read in the wild by
CreepJS
CreepJS, a research demo rather than a production detector, walks every Screen property and specifically flags an own descriptor sitting on the screen instance rather than on Screen.prototype — which is where a defineProperty spoof lands.
src/lies/index.ts: `['failed undefined properties']: (!!obj && /^(screen|navigator)$/i.test(objName) && !!(Object.getOwnPropertyDescriptor(self[objName.toLowerCase()], name) || (HAS_REFLECT && Reflect.getOwnPropertyDescriptor(self[objName.toLowerCase()], name))))` — objName 'Screen' resolves self['screen'] to the instance; plus `searchLies(() => Screen)` with no `target` ("remove target to search all properties", enumerating `[...new Set([...Object.getOwnPropertyNames(interfaceObject), ...Object.keys(interfaceObject)])].sort().forEach((name)`); and src/screen/index.ts reads `lieProps['Screen.width'] || lieProps['Screen.height'] || lieProps['Screen.availWidth'] || lieProps['Screen.availHeight'] || lieProps['Screen.colorDepth'] || lieProps['Screen.pixelDepth']`.
Every attribution traces to a published artifact. See the sources and their limits.
Nearby checks in Screen & display
- screen has an OS chrome inset (avail < screen on either axis)
taskbar-presentscreen.availWidth/availHeight describe the area left over after the OS reserves space for its own chrome — a Windows taskbar, a macOS dock… - 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.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… - the CSS layout viewport width equals window.innerWidth
css-viewport-vs-innerwidth-coherencewindow.innerWidth and the width CSS media queries evaluate against are the same quantity read two ways. matchMedia("(min-width: Npx)") is…
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 screen-descriptors belongs to.