What is screen fingerprinting?
Screen fingerprinting reads the display geometry a browser exposes: screen.width/height, availWidth/availHeight, colorDepth/pixelDepth, window.devicePixelRatio, and screen.orientation.type. On its own a resolution carries modest entropy — millions of devices report 1920×1080. Its value to a detector is that these numbers describe a physical thing, and several independent parts of the browser describe that same thing without consulting each other. See browser fingerprinting for the wider signal set.
The central mechanism is a two-source read of one quantity. screen.* is an ordinary JS property — one Object.defineProperty away from reporting anything. But the CSS media-query engine resolves device-width, device-height and resolution (in dppx) from the render surface the compositor was handed. Clearcote's free fingerprint audit tests exactly this: the screen-matchmedia check asks matchMedia("(device-width: Npx) and (device-height: Npx)") using the values screen just reported, and dpr-matchmedia asks for a resolution band around devicePixelRatio. Both answers are supposed to trace back to the same display metrics, so a disagreement says the JS surface was rewritten while rasterization continued at the true scale. Both are scored critical.
The DPR check has a subtlety worth copying: it feature-detects the resolution media feature first (reporting N/A where unsupported) and compares against a ±0.01 dppx tolerance band, not an exact value. Fractional ratios are genuinely real — Windows display scaling and Android densities produce values like 1.25 or 2.625 — and an exact matchMedia equality would fail honest browsers on a floating-point round-trip. A check that fires on real hardware teaches a detector nothing; the band keeps the assertion about contradiction rather than arithmetic.
The surrounding geometry checks are calibrated the same way. screen-plausible is only a sanity range (200–16384 px per axis) at warn: a 0×0 screen means nothing is being presented to a display, which is a headless tell rather than a contradiction. taskbar-present reports whether an OS chrome inset exists (avail smaller than screen on some axis, from a taskbar or dock) but stays info and is excluded from the score — fullscreen sessions and auto-hiding taskbars legitimately produce screen === avail. window-bounds asserts only the zoom-invariant rule: outerWidth/outerHeight must be non-zero, with the width fitting inside availWidth and the height inside screen.height (±1px). It deliberately does not assert inner ≤ outer, because zooming a page out legitimately grows innerWidth past outerWidth in a stock Chrome. A window larger than its own display is the classic residue of shrinking screen to a persona's resolution while the real window kept its size.
Two further checks read orientation and mechanism. orientation-vs-screen-dims (critical) requires portrait and height > width to agree in both directions — staying in device space, since the CSS (orientation:) media query is viewport-space and a half-screen snapped window really does resolve portrait on a landscape display; square and zero-sized screens are excluded rather than guessed at. And screen-descriptors (critical) ignores values entirely, asking whether width, height, avail*, colorDepth and pixelDepth still resolve through native Screen.prototype getters, with no own descriptors on the instance and no stray innerWidth/outerWidth names that belong to Window. That last one is the point: Object.defineProperty(screen, 'width', …) passes every value-plausibility test and still leaves the mechanism in plain view. The coherent options are to leave the screen real, or to give the browser a render surface of the size it claims — see coherence over camouflage.