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

To capture one rendered HTML section, select that element and call the browser framework’s element screenshot method—not a full-page screenshot followed by manual cropping. In Playwright, the modern approach is locator.screenshot():

await page.locator('#report-section').screenshot({ path: 'section.png' });

The locator is resolved in the page, actionability checks run, and the element is scrolled into view before the image is saved. The result is the element’s rendered region, including its current visual state.

Playwright: the recommended way to capture one section

Playwright’s Locator API is the best default for new code because the locator describes how to find the element and is resolved when the action runs. Use an ID, a distinctive class, a test identifier, or an accessible locator that identifies the intended section.

Complete Node.js example

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({
  viewport: { width: 1440, height: 900 },
  deviceScaleFactor: 1
});

await page.goto('https://example.com/report', { waitUntil: 'networkidle' });

const section = page.locator('#report-section');
await section.waitFor();
await section.screenshot({
  path: 'report-section.png',
  type: 'png'
});

await browser.close();

Install Playwright with npm install playwright. If the browser binaries are not present, run the installation command recommended for your Playwright version. Replace the URL and selector with values from your page.

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

Choosing a stable selector

  • ID: page.locator('#invoice-summary')
  • Class: page.locator('.report-section')
  • Test ID: page.getByTestId('pricing-card')
  • Accessible target: page.getByRole('region', { name: 'Usage summary' }), when the markup supplies an accessible name

A selector such as section may match several elements. Use .nth(0) only when the document order is deliberate; otherwise make the markup or test identifier more specific.

Wait for the section’s final visual state

Navigation completion does not guarantee that a chart, image, font, or client-rendered component is ready. Wait for a meaningful selector, then capture:

await page.goto('https://example.com/dashboard');
await page.locator('#sales-chart').waitFor({ state: 'visible' });
await page.locator('#sales-chart canvas').waitFor();
await page.locator('#sales-chart').screenshot({ path: 'sales-chart.png' });

For a known animation or delayed update, use a short, intentional delay. Prefer waiting for the state that matters over adding a large fixed timeout.

Useful Playwright screenshot options

  • path saves the image; omit it to receive image bytes in a buffer.
  • type selects png or jpeg; JPEG supports a quality setting.
  • scale controls whether output is based on CSS pixels or device pixels, depending on the installed version’s API behavior.
  • animations can disable or fast-forward animations where supported.
  • mask can cover sensitive or changing locators.
  • style can inject temporary CSS in versions that provide that option.
  • omitBackground can preserve transparency for formats and situations that support it.

Check the API reference for the Playwright version installed in your project before relying on a newer option or its exact default.

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

Capture bytes for processing instead of writing a file

const image = await page.locator('#report-section').screenshot({ type: 'png' });
// image is a Buffer. Upload it, hash it, or pass it to an image-processing library.

Puppeteer alternative

Puppeteer uses an element handle. Select the element, wait for it, and call ElementHandle.screenshot():

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1440, height: 900 });
await page.goto('https://example.com/report', { waitUntil: 'networkidle2' });

const section = await page.waitForSelector('#report-section', { visible: true });
if (!section) throw new Error('The section was not found');
await section.screenshot({ path: 'report-section.png', type: 'png' });

await browser.close();

Install it with npm install puppeteer. Puppeteer attempts to scroll a hidden element into view before capture. For new Playwright implementations, prefer a locator over an element handle; handles refer to one resolved DOM node and can become stale after rerendering.

What the image includes—and what it does not

Rendered pixels, not HTML source

The output is what the browser currently paints: computed CSS, loaded fonts, images, canvas content, and visible overlays. It is not a serialization of the section’s HTML.

Scrollable sections

If the target is an independently scrollable container, the screenshot represents its currently scrolled content and visible box. It does not automatically include every off-screen descendant. To capture all rows, remove the internal overflow temporarily, increase the element’s height, or capture each scroll position and stitch the images yourself.

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

Covered or obstructed content

A cookie dialog, modal, sticky header, chat bubble, or other layer can cover pixels inside the target. Element capture does not promise an unobstructed view. Dismiss or hide the overlay before taking the screenshot:

await page.getByRole('button', { name: 'Close' }).click();
await page.locator('#report-section').screenshot({ path: 'clean-section.png' });

Lazy content and fonts

Scroll the page or the relevant container to trigger lazy loading, wait for images to complete, and wait for a font-dependent element before capture. A screenshot taken too early can contain placeholders or fallback fonts even though navigation succeeded.

Element screenshot versus full-page screenshot

Use an element screenshot when the deliverable is one component, card, chart, article section, or form. Use a full-page screenshot when you need the entire scrollable document:

await page.screenshot({ path: 'full-page.png', fullPage: true });

Full-page mode captures the page’s complete scrollable height; it is not a substitute for targeting a particular element. If you need both, take separate captures so each output has an unambiguous purpose.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Common failures and fixes

“Locator resolved to multiple elements”

Your selector is not unique. Add an ID, narrow the CSS relationship, use a role/name, or intentionally choose a matching item with first() or nth() after verifying the order.

“Timeout exceeded”

The selector never became actionable, the page failed to load, or a preceding wait is too strict. Confirm the URL, log the page content, increase the timeout only when the site is genuinely slow, and wait for a stable readiness condition.

The image is blank or partially rendered

Wait for the component, images, fonts, and client-side data. Check that the section is not hidden by CSS and that an overlay is not covering it. For canvas charts, wait until the chart library has drawn.

The screenshot is clipped

Clipping is expected when the element has a fixed height and overflow: auto or hidden. Capture the visible viewport, temporarily change the style, or capture and stitch scroll positions.

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

Animations produce inconsistent images

Disable animations with the screenshot option available in your installed version, inject a test stylesheet, or wait for an application-specific “loaded” state. Avoid arbitrary long sleeps as the only synchronization mechanism.

Different machines produce different dimensions

Set the viewport, device scale factor, color scheme, locale, timezone, and fonts consistently. Screenshot dimensions are affected by CSS pixels, device pixels, browser version, and installed fonts.

Authentication or private data is missing

Create a browser context with the required storage state, cookies, headers, or login flow before navigating to the target page. Never place secrets directly in source control.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

ScreenshotNeo captures a specific element by CSS selector through one HTTP request, so you can avoid maintaining Playwright or Puppeteer infrastructure. It can also wait for a selector, delay, or network idle; run custom JavaScript and CSS; click an element; hide selectors; load lazy images in full-page captures; set cookies, headers, user agents, timezone, and geolocation; and return PNG, JPEG, WebP, or PDF output.

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.

Using cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

For element capture, add the API’s selector parameter used by your request schema. The complete option names and examples are in the ScreenshotNeo documentation.

Python:

import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
r.raise_for_status()
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}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());

ScreenshotNeo accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; those steps can be disabled. Bot checks or CAPTCHAs, 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. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000. Create a free ScreenshotNeo account.

Performance, reliability, and cost considerations

  • Reuse one browser process and contexts for batches rather than launching a browser for every section.
  • Keep selectors specific so failed captures fail quickly and predictably.
  • Use network-idle waits cautiously on pages with analytics or long-lived connections; a component-ready selector is often more reliable.
  • Set explicit timeouts and record the URL, selector, viewport, browser version, and error for reproducibility.
  • Capture at a fixed viewport and scale when images are compared in tests.
  • For high-volume jobs, an API can remove browser maintenance. ScreenshotNeo supports caching with a chosen TTL, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, and a usage API.

Frequently Asked Questions

Can I screenshot an element that is outside the viewport?

Yes. Playwright and Puppeteer attempt to scroll the target into view before capture, subject to the element being present and actionable.

Can an element screenshot include hidden descendants?

No. It captures the rendered element box and visible content. Hidden or independently scrollable descendants require a layout change, multiple captures, or a different capture strategy.

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

Which format should I choose?

Use PNG for lossless UI and text, JPEG when a smaller photographic image is acceptable, and WebP when your delivery pipeline supports it.

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.