DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsPC HealthRecommendedCrashes, freezes, slowdowns? Check your PC nowSpot repairable issues before they interrupt work.Check PC×
Skip to content
browser automation

How to Set Element Screenshot Width and Height in Puppeteer

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

Use elementHandle.screenshot() when you want an element captured at its rendered bounds. Use the screenshot clip rectangle when you need a deliberately sized crop. page.setViewport() changes the page viewport and responsive layout; it does not set the selected element’s CSS width or height.

The distinction matters because an element screenshot normally follows the element’s layout size, while a clipped screenshot follows the explicit x, y, width and height values. Device scale, fonts, images and responsive breakpoints can change the final pixel dimensions.

Choose the control that matches your goal

Goal Puppeteer control What determines the captured size
Capture one element as it is laid out ElementHandle.screenshot() The selected element’s rendered bounds; Puppeteer scrolls it into view when necessary.
Produce a crop with exact region dimensions ScreenshotOptions.clip The explicit page-coordinate rectangle: x, y, width and height.
Change responsive layout before capture page.setViewport() The page viewport, which can cause CSS media queries and responsive components to switch layouts.

These controls solve different problems. Setting a viewport to 1280×800 does not force a card, chart or component to become 1280×800, and setting an element’s CSS size does not guarantee the same number of output pixels if the device scale factor changes.

Capture an element at its rendered width and height

Wait for the selector, make sure the element is visible, and call screenshot() on the handle:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800, deviceScaleFactor: 1 });
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

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

await element.screenshot({ path: 'element.png' });
await browser.close();

The Puppeteer API documentation describes this behavior as: “This method scrolls element into view if needed, and then uses Page.screenshot() to take a screenshot of the element.” A handle that becomes detached because the framework replaced the node causes an error, so locate the element again after major re-renders.

How the natural dimensions are determined

The image follows the element’s rendered border-box region, including the effects of CSS layout, loaded fonts, images, transforms and the device scale factor. CSS width and height are measured in CSS pixels; the encoded PNG, JPEG or WebP can contain a different number of physical pixels when deviceScaleFactor is greater than one.

If the page uses an auto-sized component, wait for its meaningful ready state rather than assuming navigation alone means it is visually stable. For example, wait for a chart container, an image completion condition or an application-specific “loaded” marker before taking the shot.

Set an exact crop with clip

When the requirement is “320×180 pixels of this page region,” define the crop explicitly:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.screenshot({
  path: 'crop.png',
  clip: { x: 40, y: 80, width: 320, height: 180 },
});

clip describes a page-coordinate rectangle. It controls the captured region, not the selected element’s CSS dimensions. Use positive, intentional values and ensure the rectangle intersects the page content you expect. If you need a crop aligned to an element, read its geometry first and pass that rectangle:

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

const box = await element.boundingBox();
if (!box) throw new Error('Element has no visible bounding box');

await page.screenshot({
  path: 'target-crop.png',
  clip: { x: box.x, y: box.y, width: box.width, height: box.height },
});

Do not combine a custom clip rectangle with fullPage: true; they represent different capture intents. If you need a fixed output size that does not match the element’s aspect ratio, choose how to handle the mismatch: crop content, resize after capture, or change the page’s layout before taking the screenshot. Puppeteer’s crop itself does not redesign the element.

Control responsive layout with the viewport

Set the viewport before navigation when the site’s CSS or JavaScript responds to viewport dimensions:

await page.setViewport({
  width: 1280,
  height: 800,
  deviceScaleFactor: 1,
});
await page.goto(url);

Changing width can switch breakpoints, alter text wrapping and change the element’s rendered bounds. Changing height affects what is initially visible and can influence scripts that measure the viewport. A device scale factor changes the relationship between CSS pixels and image pixels; set it deliberately when downstream systems require predictable output.

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

An 800×600 viewport with a 240×120 element at device scale one is an illustrative example, not a universal guarantee. Real pages can produce different dimensions because of fonts, zoom, transforms, scrollbar behavior and dynamic content.

Complete reusable helper

This helper supports either natural element capture or a fixed crop and records the geometry used:

import puppeteer from 'puppeteer';

async function captureElement({ url, selector, output, crop }) {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1280, height: 800, deviceScaleFactor: 1 });
    await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60000 });

    const handle = await page.waitForSelector(selector, { visible: true, timeout: 30000 });
    if (!handle) throw new Error(`No visible element matched ${selector}`);

    if (!crop) {
      await handle.screenshot({ path: output });
      return;
    }

    const box = await handle.boundingBox();
    if (!box) throw new Error('The element has no visible bounding box');
    await page.screenshot({
      path: output,
      clip: { x: box.x + (crop.x ?? 0), y: box.y + (crop.y ?? 0), width: crop.width, height: crop.height },
    });
  } finally {
    await browser.close();
  }
}

await captureElement({
  url: 'https://example.com',
  selector: '#target',
  output: 'element.png',
});

await captureElement({
  url: 'https://example.com',
  selector: '#target',
  output: 'fixed-crop.png',
  crop: { x: 0, y: 0, width: 320, height: 180 },
});

The first call preserves the element’s rendered bounds. The second takes a 320×180 region starting at the element’s top-left corner. Validate that the crop remains inside the intended content when the element can become smaller at another breakpoint.

Full-page and below-the-fold captures

fullPage: true belongs to the page-level screenshot API and captures the whole document, not just a selected element:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.screenshot({ path: 'page.png', fullPage: true });

It is not a substitute for element.screenshot(). Full-page capture also does not automatically fetch content that an infinite-scroll application has not rendered. Scroll or trigger the application’s loading mechanism, wait for the new content, and then capture if the document must include it.

Make captures stable and repeatable

  • Use a deterministic viewport and device scale factor.
  • Wait for the target selector with { visible: true }.
  • Wait for the application’s actual visual readiness condition, such as a completed image or chart-render event.
  • Disable animations or wait until transitions finish if motion changes geometry.
  • Capture after web fonts and important images have loaded; otherwise text wrapping and element bounds may change.
  • Use a fresh handle after a framework re-render to avoid detached-element errors.
  • Keep navigation and selector timeouts explicit so a failed page does not hang a worker indefinitely.

Troubleshooting width, height and blank output

The image is not the width or height expected

Decide whether you requested natural bounds or a fixed crop. Natural bounds come from layout; use clip for an explicit region. If the page is responsive, set the viewport before navigation and check the device scale factor. Inspect boundingBox() to see the actual CSS-pixel geometry before capture.

The screenshot is blank or the call fails

Confirm that the selector matches the intended node, that it is visible and attached, and that the page has reached the state you want. A zero-area or hidden element has no useful visible box. If the site replaced the node, call waitForSelector again instead of reusing the old handle.

The element was below the fold

ElementHandle.screenshot() scrolls the element into view when needed. If scrolling triggers lazy loading, wait for the resulting image or content before capturing.

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

The responsive layout changed unexpectedly

Set the viewport before goto(), use the same device scale factor in every environment, and verify that browser zoom and CSS transforms are not changing the geometry.

The full document is missing dynamically loaded sections

fullPage captures what the document has rendered; it does not force an infinite-scroll application to load additional pages. Trigger loading and wait for the new nodes first.

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

Performance, reliability and cost considerations

Element captures are usually less work than full-page captures because the output region is smaller, but page startup, navigation, JavaScript execution and asset loading still dominate many runs. Reuse a browser process for batches while creating isolated pages, and close pages and browsers in finally blocks. For reliable automation, record the URL, selector, viewport, device scale factor, chosen mode (natural or clip), and any readiness condition alongside the output.

When exact dimensions matter, validate the encoded image dimensions in your pipeline rather than assuming CSS pixels equal file pixels. A scale factor, browser version or responsive breakpoint can change the result. The Puppeteer API reviewed for this article is version 25.12.0 as of September 29, 2026; check the current API documentation when upgrading because option behavior can change between releases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

Or skip the browser setup

ScreenshotNeo provides a website screenshot API and MCP server. A single request returns a PNG, JPEG, WebP or PDF, while options handle viewport and device presets, retina scale, full-page capture, CSS-selector element capture, custom CSS and JavaScript, waits, click actions, hidden selectors, headers, cookies, user agents, geolocation, blocking rules, resizing, caching and asynchronous jobs. Clean shots are billed only after cookie or consent banners are accepted and 60-plus known consent platforms, newsletter popups and chat widgets are removed. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status.

Use the API details in the ScreenshotNeo documentation and replace the target URL as needed:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

Its MCP server exposes take_screenshot, get_page_info and capture_pdf to Claude, Cursor and other MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.

Frequently Asked Questions

Can I set an element’s CSS width with the screenshot option?

No. Screenshot options capture the rendered result or a crop. Set CSS through the page, custom styles or application layout before capturing, then use the element screenshot or clip mode.

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

Does deviceScaleFactor change the requested clip width?

The clip values describe the page region in CSS-coordinate terms; the encoded image’s physical pixel dimensions can vary with device scale. Verify output dimensions in your image-processing step.

Should I use element.screenshot() or page.screenshot({ clip }) for a card?

Use element.screenshot() when the card’s natural rendered bounds are wanted. Use clip when a fixed rectangle is the requirement, even if that rectangle crops or includes space around the card.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
Windows Errors? Fix Them Before They SpreadFree repair scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.