Scrapeless Wiki

What Is Screen Fingerprinting? – Definition and How It Works

Informational P2 what is screen fingerprinting

Learn which screen properties are fingerprinted, why viewport and screen must agree, and the headless tells they expose.

Screen fingerprinting reads the display characteristics a browser reports β€” resolution, available area, colour depth, pixel ratio β€” and uses the combination as an identifying and automation-detecting signal.

1. The Properties

Property Meaning
screen.width / height Full display resolution
screen.availWidth / availHeight Resolution minus OS chrome
screen.colorDepth / pixelDepth Bits per pixel, almost always 24
devicePixelRatio Physical-to-CSS pixel ratio
innerWidth / innerHeight The viewport
outerWidth / outerHeight The whole browser window
screen.orientation Orientation and angle

2. The Relationships Are the Signal

Any single number is unremarkable. What detection checks is whether they form a physically possible arrangement:

  • availHeight must be less than or equal to height, and normally slightly less, because a taskbar or menu bar occupies space.
  • innerHeight must be less than outerHeight, because browser chrome exists.
  • outerWidth/outerHeight must not exceed the screen.
  • devicePixelRatio should match a plausible device class.

Violations are decisive. availHeight exactly equal to height means no OS chrome at all, which is the default in many headless configurations and rare on a real desktop.

3. Classic Headless Tells

screen.availHeight === screen.height        // no taskbar β€” unusual
window.outerHeight === 0                     // no window at all
window.outerHeight === window.innerHeight    // no browser chrome
screen.width === 800 && screen.height === 600 // an old headless default
devicePixelRatio === 1 && screen.width > 2560 // a large display with no scaling

The zero-outerHeight case is the strongest: a browser with no window dimensions is not a browser a person is using.

4. Resolution Distribution Matters

Real screen sizes cluster heavily: 1920Γ—1080 dominates desktop, with a handful of other common sizes and the standard mobile resolutions.

A resolution outside that distribution β€” 1024Γ—768, or an arbitrary 1337Γ—900 β€” is a signal precisely because it is uncommon, even though nothing about it is invalid. Choosing a common resolution matters more than choosing a large one.

5. Viewport Must Be Smaller Than Screen

A frequent misconfiguration: setting a viewport equal to, or larger than, the reported screen. On a real device the window sits inside the display with chrome above it.

context = browser.new_context(
    viewport={"width": 1512, "height": 850},          # window content area
    screen={"width": 1920, "height": 1080},           # the display
    device_scale_factor=1,
)

Setting both, with the viewport comfortably smaller, produces a coherent pair. Setting only the viewport leaves the screen at whatever the environment reports β€” frequently something that contradicts it.

6. A CDP Caveat

When driving a browser over a remote CDP connection, viewport-setting calls can be silently ignored β€” the real window keeps whatever size the remote browser was launched with, while your code believes it applied a size.

The consequence is a mismatch between what you configured and what the page reports, which is worth asserting rather than assuming:

print(page.evaluate("() => [screen.width, screen.height, innerWidth, innerHeight, outerHeight]"))

Read the values back. If they do not match what you set, the setting did not take effect.

7. Screenshots Are Not the DOM Frame

Related trap: a screenshot's dimensions need not match the layout viewport the page is using. Any logic that computes coordinates from a screenshot and then clicks them can be systematically wrong.

Prefer element-based interaction over coordinate-based clicking, and where coordinates are unavoidable, derive them from the DOM rather than from an image.

8. Summary

Screen fingerprinting reads resolution, available area, colour depth, pixel ratio, and window dimensions, and identifies both the device and the fact of automation.

The decisive signals are impossible relationships β€” availHeight equal to height, outerHeight of zero or equal to innerHeight, a viewport larger than the screen β€” so set screen and viewport together as a coherent pair, choose a common resolution, and read the values back because remote CDP connections can ignore the setting entirely.