How to Set the Viewport Size for Chromium Screenshots
Set Chromium screenshot dimensions with Playwright, understand viewport versus pixel scale, and fix common sizing problems.
Set the viewport width and height before capture. In Playwright, configure viewport when you create a browser context or in Playwright Test’s project settings; to resize an existing page, call page.setViewportSize(). For example, a 1280 × 720 CSS-pixel viewport is set with { width: 1280, height: 720 }. These values control the emulated visible area and responsive layout. They are separate from device pixel ratio, screenshot output scale, and whether the screenshot captures the full page.
1. Choose the viewport dimensions
Pick dimensions that represent the layout or breakpoint you want to inspect. There is no universally correct viewport size: a desktop layout check, a narrow mobile layout, and a tablet scenario need different widths. Height controls the visible area and can affect what appears in a viewport-only capture; width is often the key input to responsive breakpoints.
Think of screenshot sizing as four independent choices:
| Choice | What it controls | Playwright setting |
|---|---|---|
| Viewport width and height | Emulated visible area and responsive layout | viewport or page.setViewportSize() |
| Device pixel ratio | Emulated device density | deviceScaleFactor |
| Output pixel scale | CSS pixels or device pixels in the image | Screenshot scale |
| Capture scope | Visible viewport or whole scrollable page | fullPage |
2. Set the viewport in Playwright
Playwright Test configuration
Set the viewport in the Chromium project. If you spread a device preset, put the explicit viewport after it so your chosen dimensions take precedence over the preset viewport.
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
viewport: { width: 1280, height: 720 },
},
},
],
});
Then a test can navigate and take a screenshot using the configured context:
import { test } from '@playwright/test';
test('captures the desktop layout', async ({ page }) => {
await page.goto('https://example.com');
await page.screenshot({ path: 'page.png' });
});
Create a context directly
For scripts that launch Chromium themselves, pass the viewport to browser.newContext(). The following is a complete Node.js example using Playwright:
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 },
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'page.png' });
await context.close();
} finally {
await browser.close();
}
Install the package and its Chromium browser if they are not already available in your project: npm install playwright, then npx playwright install chromium. For a project that already uses Playwright Test, use its existing installation and configuration.
Resize an existing page
Use page.setViewportSize() when the page already exists and you need to change its visible dimensions. Set it before capture, and wait for any layout-dependent content to settle.
await page.setViewportSize({ width: 1600, height: 1200 });
await page.screenshot({ path: 'resized.png' });
A viewport resize can trigger responsive CSS and page resize handlers. If the page uses client-side code to rearrange content, wait for that application work before capturing.
3. Separate viewport size from screenshot resolution
Viewport dimensions are measured in CSS pixels. Setting a 1280 × 720 viewport does not, by itself, promise that the saved bitmap will be exactly 1280 × 720 physical pixels: device density and screenshot scaling also matter.
Device scale factor
Set deviceScaleFactor on the context to emulate a device pixel ratio. For example, this context uses a 1280 × 720 CSS-pixel viewport with a scale factor of 2:
const context = await browser.newContext({
viewport: { width: 1280, height: 720 },
deviceScaleFactor: 2,
});
The scale factor emulates pixel density. It is useful when checking high-density rendering, but it does not change the CSS viewport dimensions used for responsive layout.
Screenshot output scale
Playwright’s screenshot scale option controls whether output uses CSS pixels or device pixels. 'css' produces one image pixel per CSS pixel; 'device' produces one image pixel per device pixel, so a high-density capture can be larger. Choose the output scale deliberately when image dimensions or file size matter.
await page.screenshot({ path: 'page-css-scale.png', scale: 'css' });
await page.screenshot({ path: 'page-device-scale.png', scale: 'device' });
For exact option behavior and supported screenshot parameters, see the Playwright screenshot API parameters.
Viewport capture versus full-page capture
A normal screenshot captures the visible viewport. fullPage: true captures the full scrollable page instead. Increasing the viewport height is not the same as requesting a full-page screenshot: one changes the emulated visible area, while the other changes the capture scope.
await page.screenshot({ path: 'viewport.png' });
await page.screenshot({ path: 'full-page.png', fullPage: true });
4. Set the viewport with Chrome DevTools Protocol
If you are using Chrome DevTools Protocol (CDP) directly, Emulation.setDeviceMetricsOverride controls emulated device dimensions, device scale factor, and mobile emulation. The Page domain provides screenshot capture. CDP requires a debugging session attached to the relevant Chromium target, and protocol details can change between Chromium builds. Check the protocol schema for the browser version you run. If your project already uses Playwright, its context and page APIs are generally the simpler option.
See the current Chrome DevTools Protocol Page domain and confirm the Emulation domain method and parameters against your Chromium version before wiring a raw CDP client.
5. Test responsive layouts systematically
- List the layout widths or breakpoints your page must support.
- Create a separate context or test configuration for each target viewport.
- Use the same viewport dimensions for repeated comparisons.
- Set device scale factor and screenshot output scale independently if pixel density matters.
- Decide whether you need the visible viewport or the full scrollable page.
- Wait for navigation, fonts, images, and any client-side layout work required by the page before capturing.
For Playwright’s documented emulation controls and device presets, see Playwright Emulation. Device presets include viewport settings, which you can override when a test needs exact dimensions.
6. Troubleshooting viewport size problems
| Symptom | Likely cause | Fix |
|---|---|---|
| The page layout looks like the wrong device | The context inherited a preset viewport, or the explicit viewport was overridden. | Set viewport explicitly in the context or project configuration. When spreading a device preset, put your viewport after the spread. |
| The image dimensions do not match width × height | Device scale factor or screenshot scale changes output pixels. |
Check both settings. Use scale: 'css' for one output pixel per CSS pixel, or account for device pixels when using 'device'. |
| Only the first screen appears | The screenshot uses the default viewport capture scope. | Set fullPage: true to capture the full scrollable page. |
| A resize did not change the screenshot | The page was captured before the resize or before responsive client-side work completed. | Call page.setViewportSize() before capture, then wait for the relevant layout or application condition. |
| Content is clipped or unexpectedly reflowed | The chosen dimensions activate a different breakpoint, or the page has fixed-width content. | Verify the intended CSS viewport and test the breakpoint boundary on both sides. Inspect the page’s own CSS for fixed dimensions or overflow. |
| CDP rejects an emulation command | The method or parameters may not match the Chromium protocol version or attached target. | Confirm the session is attached to the correct target and consult that browser build’s protocol schema. |
7. Performance, reliability, and cost
Viewport dimensions alone do not guarantee a fast or reliable capture. Larger viewports can expose more content at once, and full-page captures may involve substantially more page content than viewport captures. High device scale factors and device-pixel output can increase image dimensions and file size. For repeatable results, pin the intended viewport and scale settings, use consistent browser versions, and wait for the page state your capture requires.
In a local Playwright workflow, the cost considerations are your browser execution environment, storage, and any infrastructure you operate; this guide does not assume a particular hosting price. If you capture many pages or do not want to manage browser setup, an API can move that work into a request.
8. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns an image or PDF, and its documented options include viewport dimensions and other capture controls. 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 \
-d viewport_width=1280 \
-d viewport_height=720 \
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={
"access_key": "YOUR_API_KEY",
"url": "https://stripe.com",
"viewport_width": 1280,
"viewport_height": 720,
},
timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
viewport_width: '1280',
viewport_height: '720',
});
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(({ writeFile }) =>
writeFile('shot.webp', Buffer.from(await res.arrayBuffer()))
);
Before a capture, ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, with response headers that report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free 1,000 screenshots per month, with no card required.
9. FAQ
Does changing the viewport change the page’s CSS breakpoints?
Yes. The viewport is the emulated visible area used by the page’s responsive layout, so changing its width can activate different breakpoints.
Should I use a device preset or explicit dimensions?
Use a preset when you want its bundled device characteristics; set an explicit viewport when the test needs particular dimensions. You can spread a preset and then override its viewport.
Can I use a viewport screenshot to capture a long page?
Use fullPage: true to request the full scrollable page. A tall viewport and a full-page capture describe different settings.
Where can I confirm the exact screenshot option names?
Check the Playwright API documentation for your installed version, and check the current CDP schema for the Chromium build when using the protocol directly.


