Playwright Full-Page Screenshot Is Too Tall: Control the Capture Height
A Playwright full-page screenshot captures the full scrollable document. Use viewport capture, a bounded clip, or an element screenshot to control its height.
To make a Playwright screenshot shorter, choose the capture area explicitly. Omit fullPage (or set it to false) for the visible viewport, use clip with a height for a fixed rectangle, or take a locator screenshot for one component. If the image has more pixels than expected on a high-DPI setup, set scale: 'css'; that changes pixel density, not the captured page extent.
Playwright defines a full-page screenshot as an image of the full scrollable page. That behavior is what makes a screenshot taller than the viewport when fullPage: true is set. See the official Playwright Screenshots guide and Page API.
1. Choose the capture area first
| What you need | Playwright approach | What it controls |
|---|---|---|
| What is currently visible | page.screenshot() or fullPage: false |
The viewport-sized page capture |
| A rectangle with a maximum height | page.screenshot({ clip: { x, y, width, height } }) |
The specific capture coordinates and dimensions |
| One card, chart, or other component | page.locator(selector).screenshot() |
The selected element |
| The entire document, at CSS pixel density | fullPage: true, scale: 'css' |
Full scrollable extent at one image pixel per CSS pixel |
These controls solve different problems: fullPage determines page extent, clip bounds a rectangle, and scale determines output pixel density. A smaller scale will not crop a long page.
2. Runnable Playwright JavaScript examples
The following standalone Node.js script uses Playwright’s Chromium browser. Install the package and browser once, then save this as capture.mjs. Replace the sample URL as needed.
npm install playwright
npx playwright install chromium
Capture only the viewport
Full-page capture is off by default. Omitting the option is enough; setting it explicitly can make the intent clearer when editing existing code.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'viewport.png' });
// Equivalent: await page.screenshot({ path: 'viewport.png', fullPage: false });
} finally {
await browser.close();
}
Set a maximum capture rectangle
Use clip when you need a fixed region, including a chosen height. The example captures an area starting at the page’s top-left corner. The dimensions are illustrative; choose values that fit the content and intended output.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({
path: 'bounded.png',
clip: { x: 0, y: 0, width: 1280, height: 1200 },
});
} finally {
await browser.close();
}
Use page coordinates for x and y and specify all four rectangle fields. A clip captures the requested region; it is not a substitute for selecting an element when the target is a specific component. If you need a region elsewhere on the page, adjust the origin and ensure the requested rectangle is appropriate for the page.
Capture one element
For a component screenshot, let the locator define the target instead of capturing the full document and cropping afterward. The locator must match an element on the page.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
await page.locator('main article').screenshot({ path: 'article.png' });
} finally {
await browser.close();
}
Keep the full page but reduce output pixel density
If the document extent is correct but the image dimensions are unexpectedly large on a high-DPI setup, use CSS-pixel scale. Playwright’s 'css' scale produces one output pixel per CSS pixel; 'device' uses device pixels. Scale does not shorten the document capture.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({
path: 'full-page-css.png',
fullPage: true,
scale: 'css',
});
} finally {
await browser.close();
}
3. Set the viewport before navigation when layout matters
The viewport can change responsive layout, which in turn can change how much content fits on screen and the dimensions of page elements. Set it when creating the page, or call page.setViewportSize() before navigating. Playwright notes that changing viewport size resets screen size and recommends setting it before navigation for pages that do not expect phone-like resizing.
import { chromium } from 'playwright';
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.setViewportSize({ width: 1280, height: 800 });
await page.goto('https://example.com', { waitUntil: 'load' });
await page.screenshot({ path: 'desktop-viewport.png' });
} finally {
await browser.close();
}
A viewport change affects viewport capture and responsive layout. It does not turn fullPage: true into a viewport screenshot: with that option enabled, Playwright still captures the full scrollable extent.
4. Troubleshoot an output that is still too tall
| Symptom | Likely cause | Fix |
|---|---|---|
| Image contains the whole long page | fullPage: true is still being passed by a helper or shared options object |
Remove it or set fullPage: false; use clip if you need a bounded region |
| Image pixel dimensions are larger than expected | scale: 'device' or a high-DPI configuration creates device-pixel output |
Use scale: 'css' to output one image pixel per CSS pixel; this will not crop the document |
| Capture has the wrong responsive layout | Viewport dimensions were set after navigation or do not match the desired layout | Set the viewport before goto(), then capture again |
| Only one component is needed, but the screenshot includes surrounding content | The page screenshot method targets the page | Capture a matching locator with page.locator(selector).screenshot() |
| Screenshot fails, crashes, or appears truncated on a very long page | Could involve browser or Playwright version, page complexity, or an environment-specific limit | Record the installed Playwright and browser versions, reduce the requested area, and reproduce with a viewport or clip capture. The cited docs do not define a universal maximum screenshot height. |
| Clip does not show the intended region | The clip origin or dimensions do not match the desired coordinates | Recheck x, y, width, and height; use an element screenshot for a component |
5. Reliability, performance, and output size
- Prefer the smallest useful capture area. Viewport, clip, and element captures avoid asking for the full document when it is not needed.
- Full-page work grows with page extent. Very long pages can require more capture work and produce larger image files. Choose CSS pixel scale if high-DPI output is unnecessarily large, or capture a smaller region when full coverage is not required.
- Control layout before capture. Use the intended viewport before navigation. For pages whose content loads or shifts asynchronously, wait for the relevant page state before taking the screenshot rather than assuming navigation completion means every dynamic element has settled.
- Do not assume a universal height ceiling. The official references cited here do not establish one global maximum image height. If a particular capture fails, investigate against the installed Playwright/browser version and the available memory and environment.
- Cost depends on where you run it. Playwright is the browser automation code in this workflow; infrastructure, compute, and storage costs depend on your own deployment. A smaller image can also reduce downstream transfer and storage needs.
6. Or skip the browser setup
If you need a screenshot without maintaining a local browser capture flow, ScreenshotNeo is a website screenshot API and MCP server. Its one-request endpoint returns an image or PDF; see the ScreenshotNeo API documentation for request options.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://example.com',
});
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', new Uint8Array(await res.arrayBuffer()));
ScreenshotNeo can remove cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, and cache hits are not billed, and response headers indicate the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up for ScreenshotNeo’s free 1,000 screenshots per month, with no card required.
7. FAQ
Does fullPage: false set a custom height?
No. It captures the viewport. Set the viewport dimensions to control that visible area, or use clip for a specific rectangle.
Can I keep the full page and make the screenshot file smaller?
scale: 'css' can reduce pixel dimensions compared with device-pixel output on high-DPI configurations. It keeps the full-page extent; it does not reduce document height.
Is there a documented maximum full-page screenshot height?
The cited Playwright documentation does not state a universal maximum height. Check the versions and environment involved in a specific failure rather than relying on an unsourced fixed limit.
Which method should I use for a chart or card?
Use a locator screenshot when one element is the intended output. It expresses the target directly and avoids capturing unrelated parts of the document.


