Fix Selenium Screenshots That Capture a Web Page at the Wrong Zoom Level
Diagnose whether Selenium screenshots look wrong because of window size, CSS viewport, page zoom, or pixel density, then fix the cause and verify it.
A Selenium screenshot that looks too large, too small, or unexpectedly cropped is usually caused by one of four different things: the outer browser window size, the page’s CSS viewport, browser page zoom, or the device pixel ratio and capture environment. Measure those separately before changing the page. Set a known window size, read back the CSS viewport and window.devicePixelRatio, then compare those measurements with the image dimensions.
Do not use CSS zoom as a general fix for browser zoom. It changes page layout and does not restore the browser’s own zoom state. Selenium has no universal cross-browser command for resetting page zoom; use a clean browser session and verify the measurements.
1. Identify which measurement is wrong
“Zoom level” can refer to several different properties. They affect each other, but they are not interchangeable.
| What to measure | What it describes | What a mismatch suggests |
|---|---|---|
| Outer window size | The browser window dimensions requested through WebDriver, including browser chrome in headed mode. | The window may not have reached the requested size, or the operating system and browser chrome leave a different page area. |
| CSS viewport | The layout area reported by window.innerWidth and window.innerHeight. |
Responsive breakpoints and page layout are using a different area than expected. |
| Page zoom | The browser’s page scaling state. | Content can appear larger or smaller, and page zoom can affect devicePixelRatio. |
devicePixelRatio |
The ratio of physical pixels to CSS pixels for the current display context. | The raster may have a different pixel density even when CSS layout dimensions are correct. It is evidence, not a standalone zoom control. |
| Screenshot pixel dimensions | The width and height of the output image. | Compare with the measured viewport and capture mode; do not assume a universal conversion formula across browsers and modes. |
Selenium provides APIs for moving and resizing browser windows because screen resolution affects how an application renders. The browser’s outer window size is not itself the CSS viewport size. Selenium window management documentation and MDN’s devicePixelRatio reference describe the relevant measurements.
2. Diagnose and fix the mismatch in Python
This runnable example uses Selenium’s Python binding to set a deterministic window size, read browser and page metrics, and save a screenshot. Install Selenium with python -m pip install selenium and make a compatible browser and driver available. Selenium’s current driver management may resolve drivers automatically in supported environments; otherwise configure the driver according to the browser and Selenium version you use.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import json
options = Options()
# For a headed run, remove this line. Headless and headed environments can
# produce different window and display metrics, so record which you use.
options.add_argument("--headless=new")
driver = webdriver.Chrome(options=options)
try:
driver.set_window_size(1280, 900)
driver.get("https://example.com")
metrics = driver.execute_script("""
return {
innerWidth: window.innerWidth,
innerHeight: window.innerHeight,
clientWidth: document.documentElement.clientWidth,
clientHeight: document.documentElement.clientHeight,
devicePixelRatio: window.devicePixelRatio,
visualViewportScale: window.visualViewport
? window.visualViewport.scale : null
};
""")
print("Outer window:", driver.get_window_size())
print("Page metrics:", json.dumps(metrics, indent=2))
driver.save_screenshot("page.png")
finally:
driver.quit()
The example reports visualViewport.scale when the browser exposes the Visual Viewport API. This value can help distinguish visual viewport scaling from layout viewport dimensions, but it does not replace checking page zoom or the capture environment. Selenium’s screenshot methods capture the current browsing context; the PNG dimensions should be inspected alongside the printed metrics. See the official Selenium WebDriver documentation.
3. Follow a measurement-first troubleshooting sequence
- Set and read back the window size. Call
set_window_size(width, height)after starting the browser, then inspectget_window_size(). If the returned outer size differs, investigate browser startup flags, window manager limits, or the execution environment before changing the page. - Measure the viewport after navigation. Read
innerWidth,innerHeight,document.documentElement.clientWidth, anddocument.documentElement.clientHeightin the selected page context. Do this after the page has navigated and any expected responsive transition has occurred. - Record pixel density. Read
window.devicePixelRatio. MDN notes that page zoom changes this value, while pinch zoom does not. Do not infer a page zoom percentage from DPR alone: display scaling and emulation can also matter. - Compare the screenshot raster with the measurements. Check the image file’s width and height. If the CSS viewport itself is wrong, correct the window or environment. If the CSS viewport is right but the raster density differs, inspect display scaling, headless versus headed mode, and any device emulation or device scale factor override.
- Check page zoom state separately. Start a fresh browser profile/session if a persisted browser preference may be carrying zoom state. Keep the browser and host display configuration consistent across runs, then measure again. There is no universal Selenium command documented for resetting browser page zoom across Chrome, Firefox, and Edge.
- Capture after the page is ready. Wait for a site-specific condition, such as a key element becoming visible or a known loading state completing, before saving the screenshot. A screenshot taken during navigation or a responsive reflow can make scaling appear inconsistent.
Chrome DevTools Protocol distinguishes CSS layout and visual viewport measurements from device metric emulation. Its device metrics override includes a deviceScaleFactor. If a test uses CDP emulation, record the override and avoid comparing it with a run that does not use the same emulation settings.
4. Apply fixes based on the evidence
The CSS viewport is smaller or larger than expected
Set the outer window size explicitly, query it again, and inspect the CSS viewport. In headed runs, browser chrome reduces the content area available inside the outer window. Headless mode, operating system display scaling, and browser versions can change the relationship. Use the measured viewport as the assertion target when the page layout is what matters.
The CSS viewport matches, but the screenshot pixels differ
Check devicePixelRatio, browser display scale, headless versus headed mode, and any CDP device metrics overrides. Keep these values fixed when comparing screenshots. Do not assume every browser or full-page capture mode produces raster dimensions by multiplying CSS dimensions by DPR; the consulted browser protocol documentation does not establish one universal conversion formula.
The page looks scaled and DPR changed
Investigate browser page zoom and the host display configuration. Because page zoom can change DPR, a changed value is useful evidence. It is not conclusive by itself. Recreate the run with a fresh profile and the same environment, then inspect both the layout viewport and output image.
You are using Internet Explorer Driver
The 100% browser zoom requirement is specific to Selenium’s legacy Internet Explorer Driver documentation. Its ignoreZoomSetting option skips the driver’s zoom check; it does not prove that coordinates or screenshots will behave correctly at another zoom level. Selenium states that standalone Internet Explorer is no longer officially supported as of June 2022. Do not apply this IE-specific rule to Chrome, Firefox, or Edge. See Selenium’s Internet Explorer Driver documentation.
Do not repair browser zoom with document CSS
Setting document.body.style.zoom or a CSS transform changes page rendering and can alter layout, coordinates, and responsive behavior. It may hide the symptom while making the page differ from a normal browser visit. Use CSS only when the application itself intentionally needs that styling, not to reset browser zoom.
5. Make screenshot runs repeatable
- Pin browser and driver versions where repeatability matters, and include both in diagnostic logs.
- Record headed or headless mode, operating system, display scale, requested outer window size, measured viewport, DPR, page zoom expectations, and any device emulation override.
- Use the same browser profile policy for every run. A clean temporary profile avoids accidentally inheriting browser preferences, including zoom state.
- Wait for the layout to settle using an application-specific readiness condition. For pages with animations, dynamic content, or lazy loading, define what “ready” means for the test.
- Keep viewport screenshots and full-page screenshots distinct in comparisons. They capture different areas and may be implemented differently by browser tooling.
- Save the measurements with the image or test artifact. When a visual diff fails, the recorded values help identify whether the page changed or the capture environment changed.
For a useful comparison record, include: browser and driver versions; headless or headed mode and operating system/display scale; requested outer window size and measured CSS viewport; DPR and CDP overrides; expected page zoom state; and viewport versus full-page capture mode.
6. Common errors and their fixes
| Symptom | Likely cause | Fix |
|---|---|---|
Calling get_window_size() reports the requested size, but the page still wraps differently. |
Outer window dimensions include browser chrome or the page’s CSS viewport differs. | Measure innerWidth and innerHeight; set expectations against the CSS viewport. |
| The same test produces different apparent scale on a developer machine and CI. | Different headless mode, display scale, browser/driver version, profile, or device metrics. | Log and standardize those settings, then compare DPR and viewport measurements. |
devicePixelRatio is not 1. |
Page zoom, display density, or device emulation can affect the ratio. | Do not force DPR blindly. Inspect the environment and overrides, and verify the screenshot output. |
| A CSS zoom workaround fixes one page but breaks another. | CSS zoom changes layout and is not browser page zoom. | Remove the workaround; correct the browser session or viewport configuration. |
| The screenshot is captured at the old dimensions after resizing. | The page has not completed navigation or responsive reflow, or resizing failed. | Read back window and viewport metrics after resize and wait for a page-specific readiness condition. |
| CDP device metrics settings appear ignored or behave differently. | Protocol support can vary with the browser and protocol version, or another emulation setting conflicts. | Check the browser’s matching DevTools Protocol definition, remove conflicting overrides, and log the effective viewport and DPR. |
| IE Driver reports a zoom mismatch. | Its legacy requirement expects 100% browser zoom. | Use the required zoom state for that driver; treat ignoreZoomSetting only as a skipped check. Prefer a supported browser for new automation. |
7. Performance, reliability, and cost
Reading viewport metrics with one script execution is inexpensive relative to navigation and image capture, and it can prevent wasted screenshot comparisons. Window resizing and page reloads add work, so set the target size early and avoid repeated corrective reloads. A fresh browser profile improves isolation but adds startup overhead; use it when profile state is a suspected source of drift.
Reliability depends on controlling the complete capture environment. A fixed window size alone does not control page zoom, DPR, browser chrome, host display scale, dynamic page readiness, or emulation. Selenium itself has no per-shot service charge described in the cited material; infrastructure and browser execution costs depend on where the test runs. The measurements above help reduce reruns and make failures diagnosable.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. If the task is simply to capture a page rather than test Selenium behavior, it avoids installing and configuring a browser for each capture. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and removed before capture; supported consent platforms, newsletter popups, and chat widgets can be removed, with each step configurable.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server lets AI agents, including Claude and Cursor, use
take_screenshot,get_page_info, andcapture_pdf. - The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is on every plan.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
9. Frequently asked questions
Does setting the browser window to 1280 × 900 guarantee a 1280 × 900 screenshot?
No. That is an outer window request. Measure the CSS viewport and inspect the saved image dimensions; browser chrome, display scaling, and capture mode affect the result.
Does window.devicePixelRatio tell me the browser zoom percentage?
No. It is a ratio of physical pixels to CSS pixels. Page zoom affects it, but display density and emulation can also matter.
Should I set DPR to 1 for stable screenshots?
Only if that matches the test’s intended environment and your browser emulation supports it. First identify the source of the mismatch and record the effective value.
Can Selenium reset zoom identically in every browser?
The cited Selenium documentation does not define a universal cross-browser page zoom reset. Use a controlled fresh session and verify browser measurements instead of assuming a reset command worked.
Is the 100% zoom rule relevant to Chrome or Firefox?
No. The cited 100% requirement is documented for Internet Explorer Driver, a legacy driver; it should not be generalized to other browsers.


