Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Logitech M185 Compact Ambidextrous 2.4 GHz Wireless Mouse - Swift Grey
  • 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).

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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
Sale
Logitech G305 Lightspeed Wireless Gaming Mouse - Black
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Logitech M185 Compact Ambidextrous Wireless Mouse with Rubber Grips - Blue
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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 finally block 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
Amazon Basics 3-Button USB Wired Mouse with Responsive Tracking, Plug & Play, Compatible with Windows and Mac, Black
  • 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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scrolling 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.Support on Ko-Fi

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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
Sale
Acer Wireless Mouse for Laptop, 2.4GHz Computer Mouse 3 Adjustable 1600 DPI
  • 【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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Frequently 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

SaleBestseller No. 1
Logitech M185 Compact Ambidextrous 2.4 GHz Wireless Mouse - Swift Grey
Logitech M185 Compact Ambidextrous 2.4 GHz Wireless Mouse - Swift Grey
Product carbon footprint: 3.97 kg CO2e; Contoured shape: Gives you more comfort and control
$14.90
SaleBestseller No. 3
Bestseller No. 4
Amazon Basics 3-Button USB Wired Mouse with Responsive Tracking, Plug & Play, Compatible with Windows and Mac, Black
Amazon Basics 3-Button USB Wired Mouse with Responsive Tracking, Plug & Play, Compatible with Windows and Mac, Black
Computer mouse for easily navigating a computer interface; click, scroll, and more; 3 buttons offer effortless fingertip control
$9.70

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.