How to Capture Sharp Retina and High-DPI Website Screenshots
Capture crisp website screenshots by choosing the right pixel scale, capture area, and file format. Includes runnable Playwright examples and troubleshooting.
To capture a sharp Retina or high-DPI website screenshot with Playwright, set the screenshot scale to "device". This produces one output image pixel per device pixel, retaining more detail than CSS-pixel output. Use scale: "css" when a smaller image with one output pixel per CSS pixel is the better fit. Then choose whether to capture the viewport, an element, or the full scrollable page.
A high-DPI capture increases output pixels; it does not restore detail missing from the site’s original images or other assets. The setting controls the screenshot’s pixel density, not the quality of the source content. [Playwright Page API]
1. Choose scale, capture area, and format
| Choice | Use it when | Trade-off |
|---|---|---|
scale: "device" |
You need a high-density image with one output pixel per device pixel. | More pixels mean larger image dimensions and usually more data to encode or store. |
scale: "css" |
You want one output pixel per CSS pixel and a smaller image. | It contains fewer output pixels for the same CSS-sized layout. |
| Viewport | You need the visible browser page at the selected viewport. | Content outside the viewport is not included. |
| Element | You need a particular component or region. | The selector must match an element that is present and visible. |
| Full page | You need the complete scrollable page. | Tall pages can create large files and take longer to capture. |
| PNG | You need lossless output for close inspection. | Files may be larger than compressed formats. |
| JPEG or WebP | You need compressed output and can accept lossy encoding. | Compression can introduce artifacts; quality controls apply to JPEG and WebP, not PNG. |
Playwright’s Page screenshot API documents "device" as its default scale. Defaults can differ between APIs: Playwright’s browser-tool screenshot guide documents CSS scale as its default. Set the scale explicitly when consistent output matters, and check the documentation for the exact API and version you use. [Page API] [Screenshot guide]
Viewport, element, and full-page captures refer to page content, not browser chrome. Full-page capture includes the full scrollable page. [Playwright screenshot guide]
2. Capture with Playwright in Node.js
The following runnable example uses Playwright’s JavaScript API. It visits a page, waits for the document to load, and saves a full-page PNG at device-pixel scale. Save it as screenshot.mjs, install Playwright with npm install playwright, install a browser with npx playwright install chromium, and run node screenshot.mjs.
import { chromium } from 'playwright';
const url = process.argv[2] ?? 'https://example.com';
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({
viewport: { width: 1440, height: 900 },
deviceScaleFactor: 2
});
await page.goto(url, { waitUntil: 'load', timeout: 30_000 });
await page.screenshot({
path: 'page.png',
type: 'png',
fullPage: true,
scale: 'device'
});
} finally {
await browser.close();
}
deviceScaleFactor controls the browser context’s device scale factor, while screenshot scale selects whether output pixels correspond to device pixels or CSS pixels. The explicit deviceScaleFactor: 2 sets up a high-density context; use the scale option to state the output mapping you want. The resulting dimensions depend on capture area and device scale. Check the image dimensions after capture rather than assuming a specific width or height.
Capture the viewport
await page.screenshot({
path: 'viewport.png',
type: 'png',
fullPage: false,
scale: 'device'
});
Capture one element
const card = page.locator('[data-testid="product-card"]');
await card.waitFor({ state: 'visible', timeout: 10_000 });
await card.screenshot({
path: 'product-card.png',
type: 'png',
scale: 'device'
});
Replace the example selector with a selector from the target page. Waiting for visibility helps avoid capturing before a dynamically rendered element appears.
Use CSS-pixel output or a compressed format
await page.screenshot({
path: 'smaller.png',
type: 'png',
fullPage: true,
scale: 'css'
});
await page.screenshot({
path: 'compressed.webp',
type: 'webp',
quality: 85,
fullPage: true,
scale: 'device'
});
The file extension can be used to infer image type, or you can set type explicitly. The API documents quality controls for JPEG and WebP; PNG is lossless and does not use the quality option. For visual inspection where compression artifacts matter, use PNG. For smaller delivery files, test the compressed format and quality that suits your use. [Playwright Page API]
3. Capture with Playwright in Python
Install the Python package and its Chromium browser with pip install playwright and playwright install chromium. Save the script as screenshot.py and run python screenshot.py https://example.com.
import sys
from pathlib import Path
from playwright.sync_api import sync_playwright
url = sys.argv[1] if len(sys.argv) > 1 else 'https://example.com'
with sync_playwright() as p:
browser = p.chromium.launch()
try:
page = browser.new_page(
viewport={"width": 1440, "height": 900},
device_scale_factor=2,
)
page.goto(url, wait_until="load", timeout=30_000)
page.screenshot(
path="page.png",
type="png",
full_page=True,
scale="device",
)
finally:
browser.close()
To capture only the viewport, set full_page=False. To capture an element, locate it and use its screenshot method:
card = page.locator('[data-testid="product-card"]')
card.wait_for(state="visible", timeout=10_000)
card.screenshot(path="product-card.png", type="png", scale="device")
4. Keep image pixels and automation coordinates straight
High-resolution screenshot pixels and mouse interaction coordinates may use different coordinate spaces. The Playwright CLI documentation notes that high-resolution screenshot capture uses device pixels, while mouse commands use CSS-pixel coordinates. Do not take a coordinate measured from the output bitmap and pass it directly to an automation command without accounting for the scale. [Playwright CLI screenshot documentation]
For example, with a device scale factor of 2, an image point at (1200, 400) can correspond to CSS coordinates around (600, 200). Treat that as an illustration of the coordinate conversion, not a universal guarantee: use the actual context settings and tool’s documented coordinate rules.
5. Command-line alternative with shot-scraper
shot-scraper offers a scale factor that multiplies output dimensions and a Retina shortcut that sets device scale factor to 2. Install it following its documentation, then capture a page with a scale factor or Retina option supported by the installed version. For example:
shot-scraper https://example.com -o page.png --retina
The scale factor increases both image dimensions and total pixel count. Confirm the generated image’s dimensions for your target output and consult the tool’s current help and documentation for exact flags. [shot-scraper documentation]
6. Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from ScreenshotNeo. A single GET request returns an image or PDF; the API accepts screenshot options including full-page capture, viewport sizing, and retina scale. 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 scale=2 \
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com", "scale": 2},
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',
scale: '2'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);
These examples request scale 2; use the API’s documented option names and output settings for the capture you need. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Only clean shots are billed, and responses identify page verdict and billing status in headers.
Sign up for 1,000 free screenshots a month, with no card required.
7. Troubleshooting blurry or oversized captures
| Symptom | Likely cause | What to do |
|---|---|---|
| Screenshot looks blurry on a high-density display | The capture uses CSS-pixel scale or a low device scale factor. | Set scale: "device" explicitly and configure the browser context’s device scale factor as needed. |
| Image is much larger than expected | Device-pixel scale or a larger scale factor multiplied output dimensions. | Use CSS scale if density detail is unnecessary, reduce the device scale factor, or capture only the required area. |
| Image dimensions differ between tools | Different APIs can have different scale defaults or context settings. | Set scale and viewport explicitly; check the exact tool’s docs and inspect the resulting dimensions. |
| Element capture is empty or errors | The selector did not match, the element is hidden, or rendering has not finished. | Use a stable selector, wait for the element to be visible, and check whether the page created it after load. |
| Image is sharp but text or assets still look low quality | The source page may provide low-resolution assets or the page itself may render at low quality. | Inspect the source content and asset variants. Increasing output scale cannot invent missing source detail. |
| Clicks land at the wrong point when using screenshot coordinates | Bitmap device pixels are being confused with CSS-pixel interaction coordinates. | Convert using the context’s device scale factor and follow the automation tool’s coordinate documentation. |
| Compressed output has visible artifacts | Lossy JPEG or WebP quality is too low for the content. | Increase quality or use PNG for lossless capture; quality does not apply to PNG. |
8. Performance, reliability, and cost
A larger capture area and higher pixel density increase the amount of image data. Full-page high-DPI screenshots can therefore take longer to encode and produce larger files than viewport or CSS-scale captures. For a practical workflow:
- Capture only the area required for the task.
- Use CSS scale for previews or layout checks that do not need device-pixel detail.
- Use device scale and PNG for close visual inspection; choose JPEG or WebP when smaller files matter more than lossless pixels.
- Set navigation and element-wait timeouts so a slow or incomplete page does not stall automation indefinitely.
- Use explicit scale, viewport, and format settings for repeatable output across environments.
Higher scale increases pixel count, but the documentation cited here does not establish a universal runtime, file-size multiplier, or quality gain across all pages and browsers. Page complexity, capture area, assets, and encoding also affect results. Compare the actual output dimensions and file size for your own target pages.
With local Playwright or shot-scraper, cost depends on the machine and infrastructure you run; the cited tool documentation does not provide a universal per-capture cost. ScreenshotNeo’s Free plan includes 1,000 shots per month with no card. Paid plans are Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free. Every feature is on every plan. Its billing behavior excludes bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits; response headers indicate the page verdict and billing status. See the API docs for options and setup.
9. FAQ
Does a Retina screenshot improve the website itself?
No. It changes output pixel density. It does not change the page or make low-resolution source assets contain more detail.
Should I always use device scale?
No. Use it when retaining device-pixel detail matters. CSS scale is appropriate when smaller output is more useful.
Does full-page capture include browser controls?
No. It captures the page’s scrollable content, not browser chrome. [Playwright screenshot guide]
Why are screenshots from two APIs different sizes?
Scale defaults, device scale factor, viewport, and capture area can differ. Set these deliberately and check the target API’s documentation.


