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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

To capture one rendered <div> in Node.js, load the page in a real browser, identify the element with a stable selector, wait until it exists and is ready, then call the element screenshot method. Playwright uses page.locator('#target').screenshot({ path: 'div.png' }); Puppeteer waits for a selector and calls ElementHandle.screenshot(). Both produce an image clipped to the matched element rather than the whole page.

What an element screenshot actually captures

An element screenshot is a crop of the browser’s rendered pixels at the element’s position and size. It is not an HTML export and it does not capture a hidden or unrendered state. CSS, fonts, images, animations, overlays and the current scroll position all affect the result.

  • Covered pixels stay covered. If a cookie dialog, modal, sticky header or another layer sits above the div, the screenshot contains that visible layer instead of the obscured content.
  • Scrollable elements are not automatically expanded. A scrollable div shows the content currently inside its scroll position. Capturing its entire scrollable history requires a separate scrolling or stitching design.
  • The page must be rendered first. A Node.js HTTP request alone cannot execute the page’s JavaScript or calculate a DOM element’s layout; use Playwright, Puppeteer or a screenshot service that runs a browser.

Use a unique selector such as #invoice-card or [data-testid="hero-card"], not a generic div selector that may match many nodes.

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

Playwright: the simplest current API

Playwright’s Locator API describes how to find an element and captures a screenshot clipped to that element’s bounds. Create a project, install Playwright, and install a browser:

mkdir element-shot && cd element-shot
npm init -y
npm install playwright
npx playwright install chromium

Save this as capture-playwright.js:

const { chromium } = require('playwright');

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

  try {
    await page.goto('https://example.com', {
      waitUntil: 'networkidle',
      timeout: 60_000,
    });

    const target = page.locator('#target');
    await target.waitFor({ state: 'visible', timeout: 15_000 });
    await target.screenshot({
      path: 'div.png',
      type: 'png',
    });
    console.log('Saved div.png');
  } finally {
    await browser.close();
  }
})();

Replace the URL and #target with your page and selector. The locator method is preferable to an old-style handle for a short capture script because the selector remains the source of truth until the action runs. A locator that resolves to multiple elements should be narrowed with an ID, a data attribute, or another selector that identifies the intended node.

Make the pixels deterministic

Waiting for visibility only proves that the element is displayed. If its contents arrive later, wait for a child, a state class or a known application condition:

await page.locator('#target .chart').waitFor({ state: 'visible' });
await page.waitForFunction(() => document.fonts.status === 'loaded');
await page.waitForTimeout(300); // only when a short animation settling delay is justified
await page.locator('#target').screenshot({ path: 'div.png' });

For repeatable output, set the viewport and device scale factor explicitly, freeze or disable animations with a stylesheet, and authenticate before navigation when the div is behind a login. The screenshot format can be PNG, JPEG or WebP in Playwright’s screenshot tooling; choose the format and quality options supported by the version you install.

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

Puppeteer: wait for a selector, then capture its handle

Puppeteer’s documented element flow waits for a selector and calls ElementHandle.screenshot(). Install it and a compatible browser package:

mkdir puppeteer-element-shot && cd puppeteer-element-shot
npm init -y
npm install puppeteer

Example:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();
  await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });

  try {
    await page.goto('https://example.com', {
      waitUntil: 'networkidle2',
      timeout: 60_000,
    });

    const element = await page.waitForSelector('#target', {
      visible: true,
      timeout: 15_000,
    });
    if (!element) throw new Error('The #target element was not found');

    await element.screenshot({ path: 'div.png', type: 'png' });
    console.log('Saved div.png');
  } finally {
    await browser.close();
  }
})();

Puppeteer’s element screenshot attempts to scroll a hidden element into view before capturing it. That behavior helps when the target is below the fold, but it does not remove overlays or expand a scrollable container. Keep the handle close to the capture operation; if the page rerenders the node, reacquire it with waitForSelector.

Playwright versus Puppeteer for a single div

Concern Playwright Puppeteer
Element API page.locator(selector).screenshot() page.waitForSelector(selector), then handle.screenshot()
Waiting style Locator assertions or locator.waitFor() Explicit waitForSelector() and page waits
Target model A locator describes how to retrieve the element An ElementHandle points to a particular DOM node
Visibility caveat Covered pixels remain covered; current scroll content is captured Attempts to scroll a hidden element into view; covered and scrollable content still need handling
Output formats PNG, JPEG and WebP are documented for screenshot tooling Use the formats and options supported by your installed Puppeteer version

Neither library is a universal performance winner. Select the one already used by your test or automation stack, then pin and periodically update its package and browser versions.

Selectors, layout and page-state edge cases

Selector matches nothing

Check the spelling, whether the element is inside an iframe or shadow root, and whether navigation has finished. For an iframe, obtain the frame first and query inside it. For a shadow root, use the framework’s supported shadow-DOM locator strategy rather than assuming a document-level query can cross the boundary.

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

The image is blank or smaller than expected

Confirm the element has non-zero dimensions, wait for its images and fonts, and inspect computed styles. A transparent background can look blank even when pixels exist. Lazy-loaded content may need the element scrolled into view before waiting for its final child.

A modal or consent banner appears

Dismiss it through the page’s own controls before the screenshot, or hide it with a narrowly scoped stylesheet only when doing so reflects your intended output. Do not blindly remove every fixed-position element: some are part of the div you need.

Animations change every capture

Inject CSS that sets transition and animation durations to zero, wait for images to complete, and capture at a fixed viewport and device scale. If the page uses a canvas or chart, wait for the application’s “ready” signal instead of relying only on network idle.

The target is clipped

Element capture follows the element’s rendered box. For a fixed-height container with overflow: auto, capture the visible region or temporarily change the style and restore it afterward. For a very tall element, verify memory and output-size limits in your deployment environment.

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.

Reliability and production practices

  • Timeouts: use separate navigation and selector timeouts so a slow page does not hide a missing selector.
  • Retries: retry transient navigation failures with a fresh page or browser context; do not endlessly retry deterministic selector errors.
  • Cleanup: close pages and browsers in a finally block so failed jobs do not leak Chromium processes.
  • Security: treat target URLs and page data as untrusted. Restrict outbound network access if users can submit arbitrary URLs, and avoid logging cookies, authorization headers or private query strings.
  • Storage: write to a unique path or stream the bytes to object storage. Check that the response finished before reporting success.
  • Concurrency: reuse a controlled browser process and limit parallel pages according to available memory. More simultaneous captures can increase contention and timeouts.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. It can capture one element by CSS selector, wait for a selector, load lazy images, run custom JavaScript or CSS, click an element, choose a viewport or device preset, and return PNG, JPEG, WebP or PDF. Cookie/consent banners, newsletter popups and chat widgets are removed before the shot; bot checks, blank pages, failed loads and cache hits are not billed, and the response reports the page verdict and billing status.

Send the target selector as the API’s element option (see the parameter names and current syntax in the ScreenshotNeo documentation). The one-call pattern is:

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

For a div-specific request, add the selector parameter documented for element capture to that same GET request. The service also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools, so Claude, Cursor and other MCP clients can request captures without you wiring browser automation.

The Free plan includes 1,000 shots per month with no card. Paid plans are Starter $5 for 3,000 shots, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000 and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan.

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

Try the free plan: create a ScreenshotNeo account and start with 1,000 screenshots a month without a card.

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

Troubleshooting checklist

  1. Open the URL in the same browser engine and confirm the selector in DevTools.
  2. Log the selector count or bounding box before capture; a zero width or height explains empty output.
  3. Wait for the specific child, font status or application-ready flag that controls the div’s final content.
  4. Check overlays, iframe boundaries, shadow roots and scroll containers.
  5. Capture a full-page diagnostic image once to verify that navigation and authentication succeeded.
  6. Record navigation time, selector wait time and screenshot time so slow stages are distinguishable.
  7. When a local script works but production fails, compare browser installation, sandbox permissions, outbound access, viewport, timezone and credentials.

FAQ

Can I capture a div without launching Chromium?

Not with Playwright or Puppeteer: both operate on a rendered browser page. Use a browser-based screenshot API if you do not want to manage that runtime.

Does an element screenshot include content below the fold?

It includes the element’s rendered box. A scrollable box shows its current scroll position rather than every hidden child.

Which selector should I use?

Prefer a stable, unique ID or data attribute owned by your application. Avoid positional selectors and generic div queries that can change as the layout evolves.

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

Why does my capture show a cookie dialog?

The dialog is part of the rendered page and may cover the target. Dismiss it in automation or use a service that handles consent overlays before capture.

Frequently Asked Questions

Can I capture a div without launching Chromium?

Not with Playwright or Puppeteer; they require a rendered browser page. A browser-based screenshot API is the alternative.

Does an element screenshot include content below the fold?

Only the element’s rendered box and current scroll position are captured.

Which selector should I use?

Use a stable unique ID or data attribute rather than a generic or positional selector.

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

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.