Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Most headless screenshot mismatches are configuration mismatches, not a mysterious Selenium bug. The browser may receive a different CSS viewport, screen scale, browser or driver build, Headless implementation, capture scope, or page state. Record and compare those values before investigating individual pixels.
This guide gives a repeatable diagnostic sequence, working Selenium examples, Chrome version notes, scope checks, CI practices, and a browser-free alternative with ScreenshotNeo.
Why headless screenshots change
Screenshot output is the result of several layers: the browser build, WebDriver and driver build, operating system or container, virtual screen, window rectangle, CSS viewport, device-pixel ratio, screenshot API, and the page state at capture time. Two tests can use the same URL and source code while producing different images when any of those inputs changes.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Repair Windows errors before they cause bigger problems3Fix the driver behind crashes, sound loss and screen glitchesHeadless does not automatically mean “different pixels.” Chrome’s current Headless and headful modes use the same browser implementation, while Headless creates platform windows without displaying them. That implementation parity does not make the surrounding environment identical. Chrome’s Headless documentation describes the unified behavior from Chrome 112 onward; from version 132.0.6793.0, the old Headless implementation is provided only as the separate chrome-headless-shell binary. Record the exact version and mode in every comparison report (Chrome Headless mode).
#1 Best Overall
- CRISP CLARITY: This 23.8″ Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
- WORK SEAMLESSLY: This sleek monitor is virtually bezel-free on three sides, so the screen looks even bigger for the viewer. This minimalistic design also allows for seamless multi-monitor setups that enhance your workflow and boost productivity
- A BETTER READING EXPERIENCE: For busy office workers, EasyRead mode provides a more paper-like experience for when viewing lengthy documents
A requested outer window such as 1,280 × 900 is not necessarily the page’s CSS viewport. Browser chrome, platform behavior, device scale, and automation settings can change the usable viewport. Measure the session you actually created rather than trusting a command-line argument.
Capture the facts from both runs first
Run this diagnostic in every environment and save its output beside the screenshot. The values let you distinguish a geometry problem from a browser, scope, or timing problem.
import json
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.add_argument("--headless=new")
options.add_argument("--window-size=1280,900")
driver = webdriver.Chrome(options=options)
try:
driver.get("https://example.com")
rect = driver.get_window_rect()
viewport = driver.execute_script("""
const vv = window.visualViewport;
return {
innerWidth: window.innerWidth,
innerHeight: window.innerHeight,
outerWidth: window.outerWidth,
outerHeight: window.outerHeight,
devicePixelRatio: window.devicePixelRatio,
visualViewport: vv ? {width: vv.width, height: vv.height, scale: vv.scale} : null
};
""")
print(json.dumps({"window_rect": rect, "viewport": viewport}, indent=2))
finally:
driver.quit()
get_window_rect() reports the WebDriver window; the JavaScript values report what the document receives. Selenium documents window sizing and notes that screen resolution can affect rendering (Working with windows and tabs). Compare these values before comparing image files.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Record the complete environment
- Browser name and exact version.
- WebDriver and driver version.
- Operating system, container image, and architecture.
- Headless implementation and every Chrome argument.
- Requested window size, observed window rectangle, CSS viewport, device-pixel ratio, and visual viewport.
- Screenshot API and scope: current viewport, window, element, or full document.
- URL, authenticated state, feature flags, test data, and capture timestamp.
Keep the page state and timing consistent as well. Dynamic content, pending fonts, images, animations, and layout work can change a screenshot even when all geometry is equal. Treat page readiness as a test-design responsibility, not as a guarantee supplied by Selenium.
Rank #2
- CRISP CLARITY: This 22 inch class (21.5″ viewable) Philips V line monitor delivers crisp Full HD 1920x1080 visuals. Enjoy movies, shows and videos with remarkable detail
- 100HZ FAST REFRESH RATE: 100Hz brings your favorite movies and video games to life. Stream, binge, and play effortlessly
- SMOOTH ACTION WITH ADAPTIVE-SYNC: Adaptive-Sync technology ensures fluid action sequences and rapid response time. Every frame will be rendered smoothly with crystal clarity and without stutter
- INCREDIBLE CONTRAST: The VA panel produces brighter whites and deeper blacks. You get true-to-life images and more gradients with 16.7 million colors
- THE PERFECT VIEW: The 178/178 degree extra wide viewing angle prevents the shifting of colors when viewed from an offset angle, so you always get consistent colors
Set the window, then verify the viewport
Set dimensions through Selenium’s window API or Chrome startup options, then read them back. Selenium’s Python API is explicit:
driver.set_window_size(1280, 900)
print(driver.get_window_rect())
Chrome also documents a command-line example pairing a screenshot with an explicit size:
chrome --headless --screenshot --window-size=412,892 https://developer.chrome.com/
The 412 × 892 value is a documentation example, not a universal standard. Choose dimensions that match your application and keep them fixed in local and CI runs. Chrome startup capabilities and options are described in the Capabilities and ChromeOptions documentation.
Do not confuse window size with CSS size
Use the returned innerWidth, innerHeight, and devicePixelRatio as the contract for visual comparison. If one run reports 1280 CSS pixels and another reports 1240, responsive breakpoints may select different layouts. If the CSS dimensions match but the pixel dimensions differ, investigate scale factor and image encoding before changing application code.
Rank #3
- Clear visuals. Fluid motion: A 144Hz refresh rate and 1ms MPRT deliver smooth, tear‑free motion across work, gaming, and streaming for clearer, more fluid viewing.
- Eye comfort: TÜV Rheinland 3‑star* certification reduces harmful blue light while preserving stunning color quality without compromise. *TÜV Rheinland 3-star eye comfort certification.
- Wide viewing angle: Get consistent views across a wide 178° /178° viewing angle.
- In-Plane Switching (IPS): See excellent color accuracy and consistency across wide viewing angles with In-plane Switching (IPS) technology.
- Ultra-thin bezels: Maximize your viewing experience with thin bezels.
Control Headless screen and scale settings
Recent Chrome Headless sessions use virtual screens that are independent of a physical monitor. Chrome documents configuring virtual-screen size and scale factor, with 800 × 600 and 600 × 800 shown as illustrative examples (Configure virtual screens in Headless mode). Apply the same screen configuration in every runner when your comparison depends on screen metrics or device-pixel ratio.
Do not infer scale from a host monitor. A container with no attached display can still produce a valid virtual screen, while two runners can expose different scale factors. Log the browser-reported devicePixelRatio and the actual output image dimensions.
Check browser, driver, and Headless implementation versions
Version drift can alter layout, screenshot encoding, font handling, or Headless behavior. Pin compatible browser and driver versions in CI and include both in failure artifacts. In Chrome, explicitly choose the current Headless mode (for example, --headless=new where your installed version supports it) instead of relying on an inherited default. If a machine uses the standalone chrome-headless-shell, treat it as a different implementation from the normal Chrome binary.
Free tools Windows power users keep installed
One-click scans. No signup required.
Chrome’s version milestones are specific: unified Headless behavior was introduced in Chrome 112, and the old implementation became a standalone binary at 132.0.6793.0. They are not a promise that all hosts render identically, so exact versions belong in your reproducibility record.
Rank #4
- CURVED FOR ENHANCED ENGAGEMENT: An immersive viewing experience with a curved monitor that wraps more closely around your field of vision; It creates a wider view, enhancing depth perception and minimizing peripheral distraction
- SMOOTH PERFORMANCE FOR SEAMLESS CONTENT: Stay in the action when playing games, watching videos, or working on creative projects; The 100Hz refresh rate reduces lag and motion blur so you don't miss a thing in fast-paced moments¹
- MORE GAMING POWER: Gain the edge with optimizable game settings; Color and image contrast can be adjusted to see scenes more vividly and spot enemies hiding in the dark; Game Mode adjusts any game to fill the screen so you can view every detail²
- KEEP IT EASY ON THE EYES: Care for your eyes and stay comfortable, even during long sessions; Advanced eye comfort technology certified by TÜV reduces eye strain by minimizing blue light and reducing irritating screen flicker²
- INCREASED VERSATILITY: Connect to more; Plug devices straight into your monitor for increased flexibility, making your computing environment even more convenient
Confirm screenshot scope before comparing heights
A surprising image height often means the two tests captured different things. Selenium’s general Chromium screenshot API documents a current-window capture (Chromium WebDriver API). A viewport capture contains only the visible document area. A full-document capture must use an API that supports that scope for the selected browser; Firefox, for example, exposes a specifically named full-page screenshot method.
Make the scope explicit
- Viewport/current window: use the normal screenshot call and compare equal CSS viewport dimensions.
- Element: locate the same element and confirm its bounding rectangle before capture.
- Full document: use the browser/API’s full-page facility, then verify that lazy-loaded content and sticky elements are handled consistently.
Do not compare a full-page image from one run with a viewport image from another. Save the scope and method name in the test metadata.
Wait for a stable visual state
Replace arbitrary sleeps with conditions tied to the page’s visual contract. Wait for the application’s loading indicator to disappear, the target element to exist and have its expected dimensions, and any data request that affects the image to complete. If fonts or lazy images matter, wait until they are available and rendered. Disable or freeze animations when your test permits it, and use identical test data and clock conditions.
Recommended Free Tools
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
wait = WebDriverWait(driver, 30)
wait.until(EC.invisibility_of_element_located((By.CSS_SELECTOR, ".loading")))
hero = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, "main")))
wait.until(lambda d: d.execute_script("""
const r = arguments[0].getBoundingClientRect();
return r.width > 0 && r.height > 0;
""", hero))
driver.save_screenshot("diagnostic.png")
Save the diagnostic screenshot and the measured values for both runs. That pair usually reveals whether the mismatch starts with geometry, implementation, scope, or readiness.
Best Value
- 【INTEGRATED SPEAKERS】Whether you're at work or in the midst of an intense gaming session, our built-in speakers provide rich and seamless audio, all while keeping your desk clutter-free.
- 【EASY ON THE EYES】 Protect your eyes and enhance your comfort with Blue-Light Shift technology. This feature reduces harmful blue light emissions from your screen, helping to alleviate eye strain during long hours of use and promoting healthier viewing habits.
- 【WIDEN YOUR PERSPECTIVE】Our sleek minimal bezel design ensures undivided attention. The nearly bezel-free display seamlessly connects in a dual monitor arrangement, delivering an unobstructed view that lets you focus on more at once, completely distraction-free.
A practical comparison checklist
- Log browser, driver, operating-system/container, and Headless versions.
- Set a fixed window size with Selenium or Chrome options.
- Read back the window rectangle, CSS viewport, visual viewport, and device-pixel ratio.
- Apply the same virtual-screen and scale configuration where relevant.
- Use the same screenshot scope and browser-specific API.
- Wait for the same application state, fonts, images, and data.
- Archive the image plus all measurements when a comparison fails.
Matching these controls improves reproducibility but cannot guarantee pixel identity on every host. If the controlled values match, investigate remaining differences in operating-system rendering, available fonts, GPU/compositor behavior, and dynamic page content as separate variables rather than blaming Headless alone.
Common failure modes and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Different line breaks or responsive layout | CSS viewport or device-pixel ratio differs | Set the window, read innerWidth/innerHeight, and align scale. |
| Image is much taller in one run | Viewport versus full-document scope | Use the same API and record the scope explicitly. |
| Only late-loading regions differ | Capture occurred before data, images, or fonts settled | Wait on application-specific readiness and element dimensions. |
| Results changed after a browser update | Browser, driver, or Headless implementation drift | Pin versions and report exact builds; compare old and new runs. |
| Headless differs from a desktop run | Screen scale, OS/container, GPU, or available fonts differ | Compare measured environment values and standardize the runner. |
| Requested size is correct but output is not | Outer window is being mistaken for CSS viewport | Query JavaScript viewport values and adjust from observed results. |
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. It also provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
Use the one-call API when you need a clean, repeatable image without maintaining browser binaries:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
See the ScreenshotNeo documentation for the full parameter set. You can request full-page or CSS-selector captures, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, clicks, waits, blocked resources, headers, cookies, user agents, timezone, geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous webhooks, bulk requests for up to 100 URLs, usage data, and the OpenAPI specification.
Every plan includes every feature. The Free plan provides 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots, with yearly billing giving two months free. Create a free ScreenshotNeo account to get started.
Frequently Asked Questions
Does disabling Headless make screenshots identical?
No. Headful mode can still differ when viewport, scale, browser version, operating system, capture scope, or page timing differs.
Should I compare PNG byte-for-byte?
Only after the rendering inputs and capture scope are controlled. Otherwise, inspect environment measurements and visual differences first; encoding metadata can differ even when the rendered scene is equivalent.
Which values belong in a CI failure artifact?
Store the screenshot, browser and driver versions, Headless arguments, window rectangle, CSS and visual viewport values, device-pixel ratio, screenshot scope, operating-system/container identity, and page-readiness state.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

