Use Playwright’s page.screenshot() with a clip rectangle when you need a precise crop:
await page.screenshot({
path: 'clipped.png',
clip: { x: 100, y: 200, width: 600, height: 400 }
});
x and y mark the rectangle’s top-left corner in CSS pixels; width and height define its size. For one DOM element, locator.screenshot() is usually simpler because Playwright determines the element’s bounds for you.
Choose the right Playwright screenshot method
The capture API depends on what “clip” means in your case. A fixed rectangle, one element, the visible viewport and the complete scrollable page are different jobs.
| Need | API | What it captures | Coordinate work |
|---|---|---|---|
| Exact geometric crop | page.screenshot({ clip }) |
A rectangle specified by x, y, width and height |
You provide all four values |
| One DOM element | page.locator(selector).screenshot() |
The selected element | Playwright calculates the element bounds |
| Current viewport | page.screenshot() |
Only the visible viewport | None |
| Entire page | page.screenshot({ fullPage: true }) |
The full scrollable page | None, but page height determines output |
Clip a fixed rectangle in JavaScript
Minimal runnable example
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 900 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
path: 'clipped.png',
clip: { x: 100, y: 200, width: 600, height: 400 }
});
await browser.close();
The rectangle is measured against the page’s rendered coordinate system. The top-left point is (100, 200), and the image is 600 pixels wide by 400 pixels high in CSS-pixel terms before any device-scale conversion.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →#1 Best Overall
Calculate a clip from page geometry
Hard-coded coordinates are useful for a stable layout, but responsive pages normally need coordinates calculated at runtime. Use an element’s bounding box when the crop should include surrounding space or multiple elements.
const card = page.locator('.pricing-card').first();
await card.waitFor({ state: 'visible' });
const box = await card.boundingBox();
if (!box) throw new Error('The pricing card has no visible bounding box');
const padding = 16;
await page.screenshot({
path: 'card-with-padding.png',
clip: {
x: Math.max(0, box.x - padding),
y: Math.max(0, box.y - padding),
width: box.width + padding * 2,
height: box.height + padding * 2
}
});
Check the resulting rectangle against the viewport and page layout. A selector that is hidden, detached or not rendered can produce no bounding box; wait for the intended state before reading geometry.
Screenshot a single element
When the subject is one DOM node, use the locator screenshot API instead of manually copying coordinates:
const header = page.locator('.header');
await header.screenshot({ path: 'header.png' });
This approach follows the element as its size changes with text, fonts and responsive breakpoints. It is also easier to read in tests and less vulnerable to unrelated content moving elsewhere on the page.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCrashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteElement states and lazy content
Make the page deterministic before capture. Wait for the element, trigger an interaction if necessary, and allow images or client-rendered content to finish.
Rank #2
const chart = page.locator('#chart');
await chart.waitFor({ state: 'visible' });
await page.waitForLoadState('networkidle');
await chart.screenshot({ path: 'chart.png', animations: 'disabled' });
If a page uses a cookie dialog, modal or sticky header, close or hide it before taking the screenshot. Otherwise the overlay can be included in an otherwise correct crop.
Viewport and full-page screenshots
Visible viewport
Omit both clip and fullPage to capture what the browser currently displays:
await page.screenshot({ path: 'viewport.png' });
Full scrollable page
Set fullPage: true when content below the fold belongs in the artifact:
Recommended Free Tools
await page.screenshot({
path: 'full-page.png',
fullPage: true
});
The default for fullPage is false. A full-page image can be very tall, so use a clip or an element screenshot when a complete page is not actually required.
Output size, scale and transparency
CSS pixels versus device pixels
The scale option controls output density:
scale: 'css'produces one image pixel per CSS pixel. It keeps files compact and is generally convenient for layout review.scale: 'device'uses device pixels. On a high-DPI context this creates a larger, sharper image and a larger file.
await page.screenshot({
path: 'retina.png',
clip: { x: 0, y: 0, width: 800, height: 500 },
scale: 'device'
});
Transparent PNG output
omitBackground: true hides the default white background and allows transparency. Use PNG for this workflow; transparency does not apply to JPEG output.
await page.screenshot({
path: 'transparent.png',
omitBackground: true,
type: 'png'
});
Clipping in Playwright Test visual assertions
For visual regression, use expect(page).toHaveScreenshot() with the same clipping concepts:
import { test, expect } from '@playwright/test';
test('navigation remains stable', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveScreenshot('navigation.png', {
clip: { x: 0, y: 0, width: 1000, height: 120 }
});
});
The screenshot assertion waits until two consecutive screenshots are identical before comparing them. It is available through the Playwright test runner, not as a generic assertion in every browser script. Keep clip coordinates, viewport settings and page state stable so a genuine layout change is not confused with capture noise.
Free tools Windows power users keep installed
One-click scans. No signup required.
Reliable clipping workflow
- Set a known browser context. Fix the viewport, device scale, timezone and any other settings that affect layout.
- Navigate to the exact state. Use an appropriate load condition and wait for client-rendered content.
- Choose scope. Use a locator for one element,
clipfor a geometric region, andfullPageonly for the complete scrollable document. - Remove transient UI. Close consent dialogs, menus and chat widgets or hide them with a test-only style.
- Choose density and format. Use CSS scale for compact artifacts, device scale for high-resolution output, and PNG when transparency is needed.
- Save or return the buffer. Omitting
pathreturns image bytes, which is useful for uploads, pixel comparisons and in-memory processing.
Troubleshooting clipped screenshots
The crop is shifted
CSS coordinates are relative to the rendered page, so a changed viewport, zoom, responsive breakpoint or scroll position can move the subject. Fix the viewport and derive the rectangle from boundingBox() rather than relying on old constants.
The element screenshot is empty or fails
Verify the selector matches the intended node, wait for state: 'visible', and check that the element has rendered dimensions. Detached nodes and elements hidden by CSS do not provide a useful capture.
Content is missing below the fold
A normal screenshot captures the viewport. Use fullPage: true, scroll to trigger lazy loading before capture, or target the specific element that contains the content.
Transparent output is white
Use omitBackground: true with PNG. JPEG cannot preserve transparency.
Rank #4
Visual tests are flaky
Wait for fonts, images and application state; disable animations where appropriate; keep the browser, viewport and clip geometry consistent. The assertion’s consecutive-identical-screenshot wait helps, but it cannot stabilize a page that is still changing.
The file is unexpectedly large
Use scale: 'css', clip a smaller region, or capture an element instead of a full page. Device-pixel output and very tall documents increase memory and storage requirements.
Performance, reliability and cost considerations
Clipping reduces the pixels written to the output, but the browser still has to load and render the page. Optimize the navigation and page state first: reuse a browser when taking many screenshots, avoid unnecessary full-page captures, and wait only for the condition your application requires. For regression suites, stable geometry is more important than maximum resolution.
Playwright itself runs locally or in your chosen infrastructure, so your cost depends on browser runtime, compute and storage. A remote screenshot API can move browser maintenance and capture infrastructure out of your application.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. Its one-call endpoint can return PNG, JPEG, WebP or PDF, and it supports element capture, full-page shots, custom CSS and JavaScript, waits, device presets, retina scale, transparent backgrounds and more.
Cookie banners, newsletter popups and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and billing result. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients.
cURL
See the ScreenshotNeo documentation for all parameters. A basic request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
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)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan. Create a free ScreenshotNeo account to get started.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Frequently asked questions
Can a clip include several separate elements?
Yes. Use one rectangle covering the region that contains them, or place the elements in a wrapper and capture that wrapper with a locator.
Does clipping change the page layout?
No. The clip option limits the output image; it does not remove content or reflow the page.
Should I use an element screenshot for a regression test?
Use it when the component is the unit you want to protect. Use a clipped page assertion when surrounding context, spacing or interactions are part of the visual contract.
Frequently Asked Questions
Can a clip include several separate elements?
Yes. Use one rectangle covering the region that contains them, or place the elements in a wrapper and capture that wrapper with a locator.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Does clipping change the page layout?
No. The clip option limits the output image; it does not remove content or reflow the page.
Should I use an element screenshot for a regression test?
Use it when the component is the unit you want to protect. Use a clipped page assertion when surrounding context, spacing or interactions are part of the visual contract.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

