How to Capture Website Screenshots with a Specific Device Scale Factor
Set a browser’s device scale factor before navigation, then choose screenshot output scale and capture scope to get the dimensions you expect.
To capture a website screenshot at a specific device scale factor, configure the browser’s emulated device metrics before navigating to the page. In Playwright, set deviceScaleFactor on the browser context. In Puppeteer, set it with page.setViewport(). Then choose the capture scope and output scale separately: those settings determine whether you capture the viewport, an element, or the full page, and how many image pixels represent each CSS pixel.
For a capture spanning W × H CSS pixels at device scale factor d, device-pixel output is expected to be about (W × d) × (H × d) pixels. This follows from the pixel definitions; capture bounds and rounding may affect the final dimensions. See the official Playwright emulation guide and Playwright screenshot documentation.
1. Device scale factor and screenshot scale
A device scale factor (often shortened to DSF) is an emulated device metric. It describes the relationship between CSS pixels and device pixels. A value of 2 means two device pixels per CSS pixel in each dimension, so an image captured at device-pixel scale can have four times as many pixels as the same CSS-sized capture at scale 1.
Keep these controls distinct:
| Control | What it affects | Example |
|---|---|---|
| Viewport width and height | The page’s CSS layout area and viewport capture bounds | 1280 × 800 CSS pixels |
| Device scale factor | The emulated relationship between CSS and device pixels | 2 device pixels per CSS pixel |
| Screenshot output scale | The mapping from CSS pixels to output image pixels, when the API exposes it | Playwright css or device |
| Capture scope | Which page region is captured | Viewport, element, clipped area, or full page |
In Playwright, scale: "css" produces one image pixel per CSS pixel, while scale: "device" produces one image pixel per device pixel. Setting deviceScaleFactor: 2 does not by itself guarantee that every screenshot will be twice as wide and high: output scale and capture scope matter too.
2. Playwright: set the context device scale factor
Create a browser context with the desired viewport and device scale factor, then create a page, navigate, and capture. Set screenshot scale explicitly when output dimensions matter.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const context = await browser.newContext({
viewport: { width: 1280, height: 800 },
deviceScaleFactor: 2,
});
const page = await context.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({
path: 'page.png',
fullPage: true,
scale: 'device',
});
await context.close();
} finally {
await browser.close();
}
This is a complete ES module example for an environment with Playwright installed. The viewport and scale factor are example choices, not universal recommendations.
- Use
scale: "device"when the image should use device pixels. At DSF 2, a 1280 CSS-pixel-wide capture will generally be about 2560 output pixels wide. - Use
scale: "css"when you want one output pixel per CSS pixel, even if the context emulates a higher-density device. - Set
fullPage: trueto capture the full page; omit it for viewport capture. For an element capture, use the locator screenshot API, for exampleawait page.locator('main').screenshot({ path: 'main.png', scale: 'device' }). - For a custom region, use the screenshot API’s clip option with CSS-pixel bounds. Check the documentation for your installed Playwright version for supported screenshot options.
Playwright’s emulation guide demonstrates setting a viewport and deviceScaleFactor on a browser context. Context-level configuration makes the intended device metrics explicit and applies them before the page is loaded.
3. Puppeteer: set the viewport before navigation
In Puppeteer, pass deviceScaleFactor to page.setViewport() before calling page.goto(). Puppeteer advises setting the viewport before navigation because some sites do not expect phones to change size.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.setViewport({
width: 1280,
height: 800,
deviceScaleFactor: 2,
});
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({
path: 'page.png',
fullPage: true,
type: 'png',
});
} finally {
await browser.close();
}
The example requests a full-page PNG. For viewport capture, set fullPage: false or omit the option. Puppeteer’s screenshot API also supports options such as clipping; consult the reference for your installed version when choosing exact option names and behavior: Page.setViewport() and Puppeteer screenshots.
4. Chrome DevTools Protocol: override device metrics directly
When your automation layer does not expose device scale factor, Chromium’s Chrome DevTools Protocol provides a lower-level route through Emulation.setDeviceMetricsOverride. For example, using a Playwright CDP session with Chromium:
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage();
const session = await page.context().newCDPSession(page);
await session.send('Emulation.setDeviceMetricsOverride', {
width: 1280,
height: 800,
deviceScaleFactor: 2,
mobile: false,
});
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'page.png' });
} finally {
await browser.close();
}
The protocol’s device metrics override accepts viewport dimensions and deviceScaleFactor; a value of zero disables the override. Protocol support and behavior can depend on the browser version. Check the current Chrome DevTools Protocol Page and Emulation references for the browser you use.
5. Manual capture in Chrome DevTools
For a one-off manual screenshot, Chrome DevTools device mode simulates device conditions and provides a viewport screenshot workflow. Its documentation also describes capturing a device frame in device-specific mode. The documented workflow does not establish a general way to enter any arbitrary custom device scale factor in the screenshot dialog; use scripted browser emulation or the protocol when the exact factor must be controlled. See Simulate mobile devices with device mode.
6. Choose scope and output dimensions
Decide what the resulting image needs to include before capturing:
| Goal | Capture choice | Dimension considerations |
|---|---|---|
| What a visitor sees without scrolling | Viewport | Viewport CSS dimensions multiplied by output pixels per CSS pixel |
| A particular component | Element or locator screenshot | Element bounds determine the CSS area; device output scales those bounds |
| A particular region | Clipped screenshot | Clip coordinates and dimensions are generally expressed in CSS pixels; verify your library’s API |
| The entire document | Full-page screenshot | Page height can be much larger than viewport height; high scale increases total pixels accordingly |
When exact output dimensions are a requirement, capture a known region and inspect the generated image dimensions. Full-page output can vary with document height, content loading, and capture behavior, so do not infer its final height from the viewport alone.
7. Device scale factor options and practical choices
- Factor 1: Useful when you want one device pixel per CSS pixel under device-scale output.
- Factor above 1: Use when emulating a higher-density display or generating a denser raster image. The resulting image uses more pixels if output is captured at device scale.
- Viewport dimensions: Choose these independently. DSF changes pixel density; viewport dimensions control the CSS layout size.
- Mobile emulation: If testing mobile-specific rendering, configure the relevant mobile metrics as well as DSF. A scale factor alone does not make a desktop viewport behave like a phone.
- Output format: PNG, JPEG, and other formats are separate from emulation. Select a format and quality settings supported by your screenshot API.
- Version: Browser automation APIs and protocol schemas can change. Match the documentation to your installed package and browser version.
8. Troubleshooting incorrect screenshot dimensions
The image has the expected CSS dimensions, not the larger device dimensions
Cause: In Playwright, screenshot scale may be css, which produces one image pixel per CSS pixel.
Fix: Set scale: "device" when device-pixel output is intended, and verify the context’s deviceScaleFactor.
The page layout changed unexpectedly
Cause: The viewport was changed after navigation or the CSS viewport dimensions differ from the ones expected by the page.
Fix: Configure the viewport and DSF before navigation. Keep viewport width and height separate from the scale factor.
The screenshot is blurry or appears resampled
Cause: The captured output may be at CSS scale, or a later image-processing step may resize it.
Fix: Capture at device scale when you need denser output, and avoid downscaling or upscaling after capture unless intended.
The output is much larger than expected
Cause: Device-scale output increases pixel count in both dimensions; full-page capture can also add substantial height.
Fix: Use CSS scale for one pixel per CSS pixel, lower the DSF, capture only the needed scope, or resize the resulting image deliberately.
Mobile behavior does not match a real device
Cause: DSF controls pixel density, not every aspect of device emulation.
Fix: Configure the viewport and other mobile metrics your workflow requires. Consult the automation framework’s emulation documentation.
The page has missing images or unfinished content
Cause: The screenshot was taken before the relevant content finished loading, or the site loads images lazily as they enter the viewport.
Fix: Choose an appropriate navigation readiness condition, wait for a known selector or application state, and scroll or otherwise trigger lazy content where necessary. Avoid assuming that network idle always means the page is visually complete.
A CDP command fails or has no visible effect
Cause: The browser may not support the command or may interpret parameters differently from the protocol version you expected.
Fix: Check the protocol reference corresponding to the browser version and confirm the session is attached to the intended page target.
9. Performance, reliability, and cost
Higher device-scale output increases image dimensions in both directions. At factor d, the pixel count for a fixed CSS area grows approximately with d²; this is a mathematical consequence of scaling both dimensions, not a benchmark. Larger images can take more memory to encode, require more transfer bandwidth, and occupy more storage. Full-page captures amplify this effect because they include additional page height.
For repeatable results, pin the browser automation package and browser version, set viewport and DSF before navigation, choose screenshot scale explicitly where available, and wait for page-specific readiness. Use the smallest capture scope and output density that meet the requirement. There is no physical capture hardware required for this browser-rendering configuration.
10. Or skip the browser setup
If you want a screenshot API call rather than managing a browser, ScreenshotNeo accepts a URL and returns a screenshot. Its API supports 12 device presets and custom viewports, but the supplied product options do not specify an arbitrary device scale factor control; use Playwright, Puppeteer, or CDP when you specifically need to set an exact custom DSF.
See the ScreenshotNeo API documentation. Example request:
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 and consent banners are accepted or removed before the shot, along with known newsletter popups and chat widgets; each cleanup step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Responses include
X-Page-VerdictandX-Billedheaders. - An MCP server gives AI agents tools including
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 to get 1,000 screenshots a month with no card.
11. Frequently asked questions
Is device scale factor the same as browser zoom?
No. Device scale factor is an emulated device metric. Browser zoom is a separate rendering control and should not be substituted for DSF when your goal is device-pixel output.
Does setting DSF change the CSS layout width?
Not by itself. The viewport’s CSS width and height determine the layout area; DSF determines the device-pixel relationship.
Can I set an arbitrary scale factor in Chrome’s screenshot dialog?
The documented device-mode workflow supports viewport capture and device conditions, but does not establish arbitrary custom DSF input in the screenshot dialog. Use browser automation or CDP for explicit control.
Which approach should I use?
Use Playwright or Puppeteer for scripted captures, Playwright when its documented CSS-versus-device screenshot scale choice is useful, CDP for lower-level Chromium control, and DevTools device mode for manual viewport captures.


