How to Set the Device Scale Factor for Full-Page Screenshots in Playwright
Set deviceScaleFactor on the browser context and choose screenshot scale explicitly to control full-page output dimensions.
Set deviceScaleFactor when creating the Playwright browser context, then request a full-page capture with fullPage: true. These are separate controls: the context setting emulates the device pixel ratio (DPR), while screenshot scale determines whether the output bitmap uses CSS pixels or device pixels. Set both explicitly when output dimensions need to be predictable.
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 },
deviceScaleFactor: 2,
});
const page = await context.newPage();
await page.goto('https://example.com');
await page.screenshot({
path: 'full-page.png',
fullPage: true,
scale: 'device',
});
With this setup, the page is laid out in a 1280 × 1024 CSS-pixel viewport, and scale: 'device' requests output at device-pixel resolution. The bitmap can therefore be larger than a CSS-pixel capture. Use scale: 'css' when you want one output pixel per CSS pixel.
1. Understand deviceScaleFactor and screenshot scale
deviceScaleFactor belongs to the browser context. It sets the emulated DPR and defaults to 1. The viewport is a separate context option expressed in CSS pixels. For example, a 1280-pixel-wide viewport with a scale factor of 2 still describes a 1280 CSS-pixel layout viewport.
The screenshot’s scale option controls the mapping from rendered CSS pixels to image pixels:
| Screenshot scale | Mapping | Choose it for |
|---|---|---|
'css' |
One bitmap pixel per CSS pixel | Compact output measured in CSS pixels |
'device' |
One bitmap pixel per device pixel | High-DPI output with more image pixels |
For a full-page screenshot, the output height follows the rendered document, not just the configured viewport height. The exact height cannot be determined from the viewport alone.
2. Complete JavaScript example
This example creates a context with explicit viewport and DPR, loads the page, and saves the full page at device-pixel scale:
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 },
deviceScaleFactor: 2,
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({
path: 'full-page.png',
fullPage: true,
scale: 'device',
});
await context.close();
} finally {
await browser.close();
}
Install Playwright and its browser binaries according to the official Playwright getting-started guide. The code uses the Chromium browser explicitly; the cited API documentation defines the screenshot and context options.
3. Python example
In Python, configure the scale factor on the context and use snake_case for the full-page screenshot option:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
try:
context = browser.new_context(
viewport={"width": 1280, "height": 1024},
device_scale_factor=2,
)
page = context.new_page()
page.goto("https://example.com", wait_until="load")
page.screenshot(
path="full-page.png",
full_page=True,
scale="device",
)
context.close()
finally:
browser.close()
4. Configure Playwright Test
Set context defaults in the test project’s use configuration, then select the screenshot scale in the individual capture or assertion:
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
viewport: { width: 1280, height: 1024 },
deviceScaleFactor: 2,
},
});
import { test, expect } from '@playwright/test';
test('captures the full page at device scale', async ({ page }) => {
await page.goto('https://example.com');
const image = await page.screenshot({ fullPage: true, scale: 'device' });
expect(image).toMatchSnapshot('full-page.png');
});
Be explicit about scale across APIs. The documented default for Page.screenshot is 'device', while Playwright Test screenshot assertions document 'css' as their default. Depending on an implicit default can make captures differ when you move between APIs.
5. Choosing viewport, DPR, and scale
- Choose the layout viewport. Set
viewportto the CSS dimensions at which the page should render. - Choose the emulated DPR. Set
deviceScaleFactoron the context. Use1for standard density or a higher value, such as2, when you need a high-DPI device environment. - Choose output pixels. Set screenshot
scaleto'css'for CSS-pixel output or'device'for device-pixel output. - Capture the document. Set
fullPage: truein JavaScript orfull_page=Truein Python.
Viewport and DPR are separate configuration values; setting one does not replace the other. If the output’s pixel dimensions matter to a downstream image pipeline, set all three explicitly and inspect the saved artifact’s dimensions.
6. Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| The screenshot is larger than expected | scale: 'device' maps output pixels to device pixels, and the context uses a DPR above 1. |
Use scale: 'css' for one bitmap pixel per CSS pixel, or keep device scale and account for the larger image. |
Changing deviceScaleFactor has no effect on output dimensions |
DPR is configured on the context, while output mapping is controlled separately by screenshot scale. |
Set the context’s deviceScaleFactor and explicitly choose scale: 'device' or 'css'. |
| “Unknown option” or the setting appears ignored | deviceScaleFactor was passed to page.screenshot() instead of context creation, or Python used the JavaScript spelling. |
Move the setting to browser.newContext(); in Python use device_scale_factor. |
| A test snapshot has different dimensions from a page screenshot | The APIs document different default screenshot scales. | Specify scale explicitly in both the page capture and test assertion. |
| The image is taller than the viewport | This is expected for fullPage: true: it captures the full scrollable document. |
Check the rendered page height; viewport height alone does not define full-page image height. |
7. Reliability, performance, and artifact size
A full-page capture’s dimensions depend on the rendered document height. A higher device scale can produce a larger bitmap, which generally means more image data to encode, transfer, or store. Choose CSS scale when compact, CSS-pixel-sized artifacts suit the job; choose device scale when the higher pixel density is needed.
Pages with changing or lazy-loaded content can produce captures that depend on page behavior at capture time. The reviewed API documentation establishes full-page capture as capture of the full scrollable page, but does not establish identical behavior for every browser engine or every dynamic and lazy-loading page. Validate such pages in the target browser and ensure the content you need has rendered before capturing.
8. Or skip the browser setup
ScreenshotNeo provides a screenshot API and MCP server. Its one-call API returns an image or PDF, and its parameters include familiar names used by other screenshot APIs. This example requests a WebP capture of a public page; see the ScreenshotNeo API documentation for request options and formats.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers say which page verdict and billing status applied. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.
9. FAQ
Does deviceScaleFactor go inside page.screenshot()?
No. Set it when creating the browser context. The screenshot call has its own scale option.
How do I take a full-page screenshot at device scale factor 2?
Create a context with deviceScaleFactor: 2, then call page.screenshot({ fullPage: true, scale: 'device' }).
Why is the full-page screenshot twice as large?
With device scale, each CSS pixel maps to device pixels. A DPR of 2 can produce roughly twice the width and height in pixels compared with CSS scale, depending on the rendered page dimensions.
Does full-page capture use the viewport height as the image height?
No. The full-page option captures the full scrollable page, whose rendered height can exceed the viewport.
Official Playwright references
- Page.screenshot API: full-page capture and screenshot scale.
- Browser.newContext API: context options including device scale factor.
- Emulation guide: viewport and device configuration.
- Playwright Test screenshot assertions: assertion options and their documented scale default.


