What Is Screen Fingerprinting? β Definition and How It Works
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:
availHeightmust be less than or equal toheight, and normally slightly less, because a taskbar or menu bar occupies space.innerHeightmust be less thanouterHeight, because browser chrome exists.outerWidth/outerHeightmust not exceed the screen.devicePixelRatioshould 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.