ScreenshotNeo

BlogHow-to

Playwright Screenshot on Windows: Set Viewport and Device Scale Factor

Set a Playwright screenshot’s viewport and device scale factor on Windows. Learn how CSS and device pixel output affect image dimensions and consistency.

By the ScreenshotNeo team4 October 20267 min read

To control a Playwright screenshot’s dimensions on Windows, set viewport and deviceScaleFactor when creating a browser context, then choose the screenshot’s scale. The viewport controls the emulated visible page area; the scale controls whether output pixels correspond to CSS pixels or device pixels.

This works the same way on Windows as on other hosts. For predictable initial rendering, configure the context before creating the page and navigating:

const context = await browser.newContext({
  viewport: { width: 1280, height: 720 },
  deviceScaleFactor: 2,
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'screenshot.png', scale: 'device' });

With a 1280 × 720 CSS viewport, device scale factor 2, and scale: 'device', the output is typically 2560 × 1440 pixels. Use scale: 'css' instead when you want output dimensions to match the CSS viewport, even with a high device scale factor.

1. Understand viewport, device scale factor, and screenshot scale

Setting What it controls Typical use
viewport The emulated visible page area in CSS pixels, such as 1280 × 720. Reproduce a desktop, tablet, or mobile layout breakpoint.
deviceScaleFactor The emulated device pixel ratio (DPR). Render as a standard-density or high-density device.
screenshot({ scale }) How screenshot output pixels map to CSS pixels. Choose compact CSS-sized output or device-pixel output.
screen The emulated screen dimensions exposed to the page. Set screen emulation separately when it must differ from the viewport.

scale: 'css' produces one image pixel per CSS pixel. scale: 'device' produces one image pixel per device pixel. For a viewport width W, height H, and device scale factor D, device-scale output dimensions are generally W × D by H × D. A factor of 2 therefore means about four times as many pixels overall, before considering image compression.

Playwright documents a default context viewport of 1280 × 720 and a default deviceScaleFactor of 1. Set values explicitly when dimensions matter so your code does not depend on defaults.

2. Set the context before opening the page

For a stable screenshot setup, create a context with the desired viewport and device scale factor, then create and navigate the page. This ensures the site sees those emulated conditions during its initial load.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch({ headless: true });
  const context = await browser.newContext({
    viewport: { width: 1440, height: 900 },
    deviceScaleFactor: 1,
  });
  const page = await context.newPage();

  await page.goto('https://example.com', { waitUntil: 'load' });
  await page.screenshot({ path: 'desktop.png', scale: 'css' });

  await context.close();
  await browser.close();
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

Install Playwright in your project with npm install playwright. If the browser binaries are not installed in your environment, run npx playwright install chromium. The example uses Chromium; you can use another Playwright browser if it is installed.

Choose dimensions for the job

  • Desktop layout check: choose the CSS viewport dimensions that represent the target layout, then use factor 1 and CSS scale for output with matching dimensions.
  • High-density image: keep the target CSS viewport, set a higher device scale factor, and capture with device scale.
  • Visual regression baseline: explicitly set all three values—viewport, device scale factor, and screenshot scale—and keep them unchanged between baseline creation and comparison.
  • Responsive breakpoint test: change the viewport width to cross the breakpoint. Increasing device scale factor does not make the CSS viewport wider.

3. Resize an existing page

If a page already exists, use page.setViewportSize() to change its viewport:

await page.setViewportSize({ width: 1280, height: 720 });
await page.screenshot({ path: 'resized.png', scale: 'css' });

Set the viewport before navigation when the site’s first render depends on its initial size. A later resize changes the page and resets its emulated screen size. If you need screen dimensions configured independently, set both screen and viewport in the browser context.

Changing the viewport is useful for testing responsive layouts, but it is not the same as changing screenshot pixel density. If your screenshot is too large in pixels, inspect deviceScaleFactor and scale as well.

4. Keep screenshots consistent on Windows

Windows does not require a special viewport or device scale factor option. These are browser emulation settings. The host can still affect rendering: Playwright notes that screenshots may vary with the operating system, browser version, settings, hardware, power source, and headless mode.

For visual comparisons, create and compare baselines in the same environment where possible. Keep the browser engine and version, viewport, device scale factor, screenshot scale, headless setting, and relevant system conditions consistent. A baseline captured on Windows may differ from one produced on another operating system even when the page code and emulation settings match.

5. Troubleshooting

Symptom Likely cause Fix
The screenshot is twice as wide and tall as expected. deviceScaleFactor is 2 and output uses scale: 'device'. Use scale: 'css' for CSS-pixel dimensions, or set the factor to 1 if device-density rendering is not needed.
The image has four times as many pixels overall. Both output dimensions doubled because the device scale factor doubled. Remember that doubling width and height multiplies total pixels by four. Choose the required output scale deliberately.
The page has the wrong responsive layout. The CSS viewport width is different from the intended breakpoint, or the viewport was set after initial navigation. Set the intended viewport in browser.newContext() before creating the page and navigating.
Changing viewport size does not change image pixel density. Viewport dimensions control the visible CSS area, not the screenshot’s CSS/device pixel mapping. Set deviceScaleFactor and select scale: 'css' or scale: 'device'.
page.setViewportSize() changes page behavior unexpectedly. The resize happened after navigation; the page may react to the new viewport, and the screen size is reset. Prefer context settings before navigation. Configure screen and viewport together if screen emulation matters.
Visual diffs remain despite identical dimensions. Rendering environment or browser conditions differ. Use the same OS, browser version, headless mode, and relevant host conditions for capture and comparison.
Playwright cannot launch a browser. The required browser binary may not be installed, or launch dependencies may be unavailable. Install the selected Playwright browser with npx playwright install chromium and check the launch error for environment-specific dependencies.

6. Performance, reliability, and cost considerations

Higher device scale factors create more image pixels, which can increase screenshot memory use, encoding time, and file size. Use the lowest factor that meets the visual or downstream-resolution requirement. CSS scale is usually suitable for layout review and visual baselines where CSS dimensions are the comparison unit; device scale is useful when the output itself needs high-density pixels.

Explicit context configuration improves repeatability, but it cannot make rendering identical across different host environments. Keep capture and comparison environments aligned and wait for the page state your task needs before taking the screenshot. If the page uses delayed content, choose an appropriate navigation or readiness condition in your capture code rather than assuming that navigation alone means every visual element has settled.

Self-hosted Playwright has no per-screenshot ScreenshotNeo charge, but you are responsible for the Windows machine or runner, browser installation, execution time, storage, and maintenance. Large high-density captures can consume more resources. For repeatable output, pin your project dependencies and standardize the runner as part of your visual testing setup.

7. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. Its capture can accept cookie and consent banners like a visitor, then remove 60+ known consent platforms, newsletter popups, and chat widgets before taking the shot; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and each response identifies the page verdict and billing status in headers. AI agents can use its MCP server tools: take_screenshot, get_page_info, and capture_pdf.

For a 1280 × 720 capture, request the target URL directly. See the ScreenshotNeo API documentation for options such as viewport presets, custom viewport dimensions, and retina scale.

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}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await import('node:fs/promises').then(async (fs) => {
  await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));
});

ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Every feature is available on every plan.

Sign up free for 1,000 screenshots a month, no card required.

8. FAQ

Is the viewport measured in Windows display pixels?

The Playwright context viewport is an emulated browser viewport in CSS pixels. The Windows display’s scaling setting is not the value to copy into viewport.

Does device scale factor change CSS breakpoints?

No. Responsive CSS layout responds to the CSS viewport. Device scale factor emulates pixel density and affects device-pixel screenshot output.

Should I use CSS scale or device scale for screenshots?

Use CSS scale when you want image dimensions to follow the CSS viewport. Use device scale when you need output at the emulated device pixel density.

Can I set a different screen size from the viewport?

Yes. Configure screen and viewport in the browser context when the page needs those emulated dimensions to differ.