Use a Playwright Locator and call locator.screenshot(). For a scrollable container, the image contains only the content currently visible at that container’s scrollTop; it does not automatically stitch the element’s entire internal scroll range. Set the scroll position first, wait for content, then capture.
Capture a scrollable element at a chosen position
This is the smallest working pattern in TypeScript:
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage();
await page.goto('https://example.com/dashboard');
const panel = page.getByTestId('scrolling-container');
await panel.evaluate((element) => {
element.scrollTop = 500;
});
await panel.screenshot({ path: 'panel.png' });
await browser.close();
The value 500 is only an example. Use an offset that matches the portion you need. The locator must identify the actual element with overflow: auto, overflow: scroll or equivalent behavior, rather than a wrapper around it. Playwright’s screenshots guide demonstrates element screenshots, while the Locator API defines how a scrollable container is rendered.
What locator.screenshot() includes
It captures the element’s bounds and current viewport
A locator screenshot is clipped to the target element’s bounds. When the target is a scrollable container, only the rows, cards or text currently inside that container’s viewport appear. Calling the method does not turn the container into a tall image and does not capture content above or below the current internal scroll position.
Recommended Free Tools
#1 Best Overall
- Compact Mouse: With a comfortable and contoured shape, this Logitech ambidextrous wireless mouse feels great in either right or left hand and is far superior to a touchpad
- Durable and Reliable: This USB wireless mouse features a line-by-line scroll wheel, up to 1 year of battery life (2) thanks to a smart sleep mode function, and comes with the included AA battery
- Universal Compatibility: Your Logitech mouse works with your Windows PC, Mac, or laptop, so no matter what type of computer you own today or buy tomorrow your mouse will be compatible
- Plug and Play Simplicity: Just plug in the tiny nano USB receiver and start working in seconds with a strong, reliable connection to your wireless computer mouse up to 33 feet / 10 m (5)
- Better than touchpad: Get more done by adding M185 to your laptop; according to a recent study, laptop users who chose this mouse over a touchpad were 50% more productive (3) and worked 30% faster (4)
Playwright scrolls the target into page view
Before taking the image, Playwright performs its normal actionability checks and scrolls the element into the page viewport. That page-level movement is separate from changing the element’s own scrollTop. Set the internal offset after the locator resolves and before the screenshot call when the exact panel position matters.
Covered or detached elements change the result
If another element covers part of the panel, the covered pixels are not magically revealed. If the element is removed and recreated while the operation is running, the call can throw because the original target detached from the DOM. Use a stable locator and wait for the application state that creates the final panel.
Choose a scrolling method
Set scrollTop directly
Use locator.evaluate() when you need a deterministic offset, such as the top of a known page in a virtualized list:
const panel = page.locator('[data-testid="results-panel"]');
await panel.waitFor();
await panel.evaluate((element) => {
element.scrollTop = 1_200;
});
await panel.screenshot({ path: 'results-1200.png' });
This changes the element’s scroll position without simulating a user’s input. If the site reacts asynchronously to scrolling, wait for the newly requested content before capturing (shown below).
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Use a mouse wheel for user-like scrolling
Hover the container, then send a wheel delta. This is useful when the application listens for wheel events or only loads more content after realistic input:
const panel = page.getByTestId('scrolling-container');
await panel.hover();
await page.mouse.wheel(0, 700);
await panel.screenshot({ path: 'after-wheel.png' });
The Playwright input guide describes mouse scrolling and programmatic scrolling. A positive deltaY generally moves downward; the resulting offset depends on the page, browser and current position.
Rank #2
- The next-generation optical HERO sensor delivers incredible performance and up to 10x the power efficiency over previous generations, with 400 IPS precision and up to 12,000 DPI sensitivity
- Ultra-fast LIGHTSPEED wireless technology gives you a lag-free gaming experience, delivering incredible responsiveness and reliability with 1 ms report rate for competition-level performance
- G305 wireless mouse boasts an incredible 250 hours of continuous gameplay on just 1 AA battery; switch to Endurance mode via Logitech G HUB software and extend battery life up to 9 months
- Wireless does not have to mean heavy, G305 lightweight mouse provides high maneuverability coming in at only 3.4 oz thanks to efficient lightweight mechanical design and ultra-efficient battery usage
- The durable, compact design with built-in nano receiver storage makes G305 not just a great portable desktop mouse, but also a great laptop travel companion, use with a gaming laptop and play anywhere
Bring a particular child into view
If your goal is a row or card rather than an exact pixel offset, scroll that child into view:
const panel = page.getByTestId('scrolling-container');
const targetRow = panel.getByRole('row', { name: 'Invoice 1042' });
await targetRow.scrollIntoViewIfNeeded();
await panel.screenshot({ path: 'invoice-row-context.png' });
This positions the child as needed to make it visible. It does not guarantee a particular top margin or a specific scrollTop, so use direct assignment when pixel-stable positioning is required.
Complete runnable example
Create a project, install Playwright, and save the following as capture-panel.ts (or translate the same calls to JavaScript):
npm install playwright
npx playwright install chromium
import { chromium } from 'playwright';
async function main() {
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
try {
await page.goto('https://example.com/dashboard', {
waitUntil: 'domcontentloaded'
});
const panel = page.getByTestId('scrolling-container');
await panel.waitFor();
await panel.evaluate((element) => {
element.scrollTop = 500;
});
await panel.screenshot({
path: 'panel.png',
animations: 'disabled'
});
} finally {
await browser.close();
}
}
main().catch((error) => {
console.error(error);
process.exitCode = 1;
});
Replace the URL and test ID with values from your application. animations: 'disabled' stops CSS animations, CSS transitions and Web Animations for the capture. Finite animations are fast-forwarded to completion; infinite animations are canceled to their initial state, which makes repeated images more comparable. This option is documented in the Locator API.
Wait for the panel’s content before capturing
Changing scrollTop can trigger a fetch, virtualization or lazy rendering. A screenshot taken immediately afterward may show a loading skeleton or an empty section. Wait for a concrete condition that represents readiness in your application:
await panel.evaluate((element) => {
element.scrollTop = 1_000;
});
await page.getByTestId('row-1000').waitFor();
await panel.screenshot({ path: 'loaded-section.png', animations: 'disabled' });
For a network-driven panel, wait for the specific response or an application-ready marker rather than inserting an arbitrary sleep. There is no universal wait value: different sites render at different times. If the list is infinite, deliberately scrolling can be what triggers additional items to load. Scroll, wait for the newly expected item, and only then capture.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
- Compact Mouse: With a comfortable and contoured shape, this Logitech ambidextrous wireless mouse feels great in either right or left hand and is far superior to a touchpad
- Durable and Reliable: This USB wireless mouse features a line-by-line scroll wheel, up to 1 year of battery life (2) thanks to a smart sleep mode function, and comes with the included AA battery
- Universal Compatibility: Your Logitech mouse works with your Windows PC, Mac, or laptop, so no matter what type of computer you own today or buy tomorrow your mouse will be compatible
- Plug and Play Simplicity: Just plug in the tiny nano USB receiver and start working in seconds with a strong, reliable connection to your wireless computer mouse up to 33 feet / 10 m (5)
- Better than touchpad: Get more done by adding M185 to your laptop; according to a recent study, laptop users who chose this mouse over a touchpad were 50% more productive (3) and worked 30% faster (4)
Scrollable element versus full-page screenshot
| Need | API | What is captured |
|---|---|---|
| Visible portion of one element | locator.screenshot() |
The element’s bounds at its current internal scroll position. |
| Entire document | page.screenshot({ fullPage: true }) |
The full scrollable page, as if the page fit on a very tall screen. |
| One element’s complete internal scroll range | No documented built-in locator option in the cited API | Capture separate offsets and compose them with an image tool, or implement application-specific stitching. |
fullPage: true applies to a page screenshot; it does not change the documented behavior of a locator screenshot aimed at an internal scroll container:
await page.screenshot({ path: 'whole-page.png', fullPage: true });
Do not substitute an ElementHandle just to obtain a taller result. The ElementHandle screenshot guidance is deprecated in favor of locator-based operations; use a Locator for a live, retryable target.
Capture several sections when you need the whole internal list
Because a locator screenshot shows one internal viewport, a complete record can be made from several images at known offsets:
const panel = page.getByTestId('scrolling-container');
const offsets = [0, 800, 1_600];
for (const offset of offsets) {
await panel.evaluate((element, value) => {
element.scrollTop = value;
}, offset);
await page.waitForTimeout(100); // replace with a real readiness condition
await panel.screenshot({
path: `panel-${offset}.png`,
animations: 'disabled'
});
}
The delay above is only a placeholder for a condition you control; for production captures, wait for a row, loading marker or response that proves the offset is ready. The official documentation cited here does not specify a built-in locator setting that stitches these positions into one image. If you need one artifact, compose the captures yourself while accounting for overlap, sticky headers and the panel’s borders.
Make captures repeatable
- Fix the viewport: create the page with an explicit width and height so responsive breakpoints do not change the panel’s dimensions.
- Disable motion: pass
animations: 'disabled'when transitions or blinking indicators would make visual comparisons noisy. - Use a stable target: prefer a test ID or accessible role over a generated class name.
- Wait for real readiness: confirm the target row, image or empty-state marker exists after scrolling.
- Check overlays: close dialogs, cookie notices and tooltips that cover the panel, or deliberately capture them if they are part of the test.
- Keep the browser lifecycle bounded: close the browser in a
finallyblock so a failed screenshot does not leave orphaned processes.
Troubleshooting
The image always shows the top rows
You may be scrolling the page, not the panel. Inspect which element has the scroll bar and set that element’s scrollTop. If the panel is inside an iframe, obtain the appropriate frame locator before selecting it.
The screenshot is blank or contains a spinner
The offset likely triggered asynchronous rendering. Wait for a specific item or ready marker after changing the scroll position. Also verify that the URL loaded successfully and that the locator points to the rendered panel rather than a hidden template.
locator.screenshot() times out
The locator may match no element, the element may remain hidden, or an overlay may prevent actionability. Confirm the selector in the browser, wait for the panel to be attached and visible, and remove or dismiss blocking UI. A target that detaches during capture should be located again after the component finishes re-rendering.
Rank #4
- Computer mouse for easily navigating a computer interface; click, scroll, and more
- USB-A wired connection; if existing device only supports USB-C, an additional adapter will be required
- High-definition (1000 dpi) optical tracking ensures responsive cursor control for precise tracking and easy text selection
- 3 buttons offer effortless fingertip control
- Plug-and-go ready for instant use
The lower part is covered
Playwright captures visible pixels. A fixed header, modal, tooltip or another panel can cover the target. Close the covering element or change the page state before taking the screenshot; the API will not reveal obscured content.
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 reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchScrolling does not load more rows
Some lists respond only to wheel events or require the last sentinel to enter view. Hover the panel and use page.mouse.wheel(), then wait for the next row. If the list is virtualized, capture each offset only after the expected rows have been rendered.
Two runs produce different pixels
Animations, responsive dimensions, late-loaded assets and changing data are common causes. Fix the viewport, disable animations, wait for assets and use deterministic test data where possible.
Can I get one stitched image with a single option?
The cited Locator API documents the current viewport behavior but does not document a built-in option for stitching every internal scroll position. Capture sections separately and compose them, or implement a page-specific stitching routine.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Performance, reliability and cost considerations
Playwright screenshots run in your browser process, so the practical cost is the browser’s CPU, memory and storage plus the time needed for navigation and rendering. Large panels, high device scale factors and many offset captures increase image size and work. Reuse a browser for a batch of pages, create isolated contexts when state must differ, and avoid capturing offsets that cannot add new content.
Reliability comes from explicit state checks rather than a larger fixed delay: identify the panel, set or perform the scroll, wait for the content that should appear, disable motion, and capture. Record the offset and application state alongside each image so a failed visual check can be reproduced. When a site changes its markup, update the locator rather than silently accepting a screenshot of the wrong element.
Best Value
- 【Plug and Play for Home/Office/School】The wireless computer mouse features 2.4GHz connectivity, delivering a stable, interference-free connection up to 32ft. Designed for 𝐦𝐞𝐝𝐢𝐮𝐦 𝐭𝐨 𝐥𝐚𝐫𝐠𝐞 𝐬𝐢𝐳𝐞𝐝 𝐡𝐚𝐧𝐝𝐬, it ensures comfortable use all day. Simply plug in the USB-A receiver for instant pairing—no drivers needed. 📌📌 If the mouse isn’t suitable, place the USB receiver in the battery compartment and return both.
- 【3 Levels Adjustable DPI】This travel USB mouse offers 3 adjustable DPI settings (800, 1200, 1600), allowing you to customize sensitivity for precise design work. Effortlessly switch to match your task and elevate your productivity. 📌 Please remove the film at the bottom of the mouse before use.
- 【Effortless Browsing】Equipped with forward and backward buttons, this computer mice streamlines your workflow, making it easy to navigate through web pages and files with a simple click. 📌Side button does not work on Mac.
- 【Visible Indicator Light】 The pc mouse features a visual indicator for DPI levels and low battery alerts. The red light flashes once for 800 DPI, twice for 1200 DPI, and three times for 1600 DPI. When the battery level is below 10%, the light flashes red until the mouse is completely out of power.
- 【Click to Wake】With smart sleep mode, it saves power by standby after 10 inactive minutes, just 2-3 clicks to wake. This efficient design delivers 3x longer battery life than motion-wake mice. Engineered for durability, its buttons and scroll wheel are tested for 10 million clicks, ensuring long-term reliability and consistent performance.
Or skip the browser setup
For a remote URL where you do not need Playwright-specific interaction, ScreenshotNeo provides a single screenshot request. Its API can wait for a selector or delay, run custom JavaScript, capture one CSS-selected element, load lazy images in a full-page capture, set viewport and device presets, and return PNG, JPEG, WebP or PDF.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for the request parameters. The service accepts cookies, headers, user agents, timezone and geolocation settings when a page requires them. Before capture it accepts cookie or consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether it was billed.
It also includes an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to get started.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Frequently asked questions
Does the element need a fixed height?
No. It must be a resolved, visible element, and it must actually expose a scrollable viewport for an internal offset to matter. A container whose content is already fully visible has nothing to scroll.
Should I use scrollHeight to find the final offset?
You can read the element’s dimensions in page code, but the useful capture positions depend on the viewport height, sticky content and virtualization. Select offsets based on the content you need and verify that the expected item is rendered.
Will screenshots include content loaded only after scrolling?
They can, provided the scroll triggers loading and you wait until that content is present. The screenshot call itself is not a guarantee that an infinite list has finished fetching.
What if I need to mimic a real user exactly?
Hover the container and use page.mouse.wheel(), then wait for the same UI signal a user would see. Direct scrollTop assignment is more deterministic when event-level behavior is not part of the requirement.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Repair Windows errors before they cause bigger problems3Scan for outdated or missing drivers - takes under a minuteFrequently Asked Questions
Can Playwright capture the entire internal scroll area automatically?
The documented locator screenshot captures only the currently visible portion. Capture multiple positions and compose them when a single stitched artifact is required.
Why does fullPage: true not make my panel screenshot taller?
That option belongs to page.screenshot() and applies to the document. It does not alter a locator screenshot’s internal scroll-container behavior.
Which Playwright API should replace an ElementHandle screenshot?
Use a Locator and call locator.screenshot(); locator operations are the current documented approach.
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.

