October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
headless browsers

How to Fix PhantomJS Screenshots That Are Taller Than the Webpage

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

The usual fix is to set both properties: use page.viewportSize to establish the browser’s layout viewport, then set page.clipRect to the exact rectangle you want in the image. A viewport setting alone does not guarantee that page.render() will crop the output to that size, so PhantomJS can produce an image taller than the visible browser area.

Why the screenshot is taller than the viewport

PhantomJS has two separate dimensions that are easy to confuse:

  • page.viewportSize sets the dimensions of the headless browser viewport. The page lays out responsive content as if it were being viewed through that browser window.
  • page.clipRect sets the rectangle that is actually included in the rendered image. Its top, left, width and height values define the capture bounds.

These settings serve different purposes. If you set only viewportSize, the page may still be rendered beyond the visible fold. A page with content below the fold can therefore produce a tall image even though the layout viewport is, for example, 1024 by 768 pixels. To obtain a viewport-sized screenshot, explicitly use a clip rectangle beginning at the top-left corner and matching the desired width and height.

A tall output is not automatically an error. It is correct when your intention is to preserve the entire page, including content below the fold. The first decision is therefore whether you want a fixed viewport image or a full-page image.

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.

Choose the capture you actually need

Goal Configuration Expected height Typical use
Viewport-only screenshot Set viewportSize; set clipRect to top: 0, left: 0 and the same width and height Exactly the clip rectangle’s height Testing a visible browser state, responsive layouts, or a hero section
Full-page screenshot Set the viewport for layout, but do not constrain the capture to a viewport-sized rectangle Tall enough to include content below the fold Documentation, long articles, or archival captures

The 1024 × 768 dimensions often used in examples are configuration values, not a guaranteed output size. Replace them with the dimensions required by your test or design.

Fixed-viewport fix in PhantomJS

Complete JavaScript example

Set the viewport before opening the URL so that responsive layout is calculated at the intended size. After a successful load, assign the clip rectangle immediately before rendering:

var page = require('webpage').create();
var width = 1024;
var height = 768;

// Establish the browser's layout viewport before loading the page.
page.viewportSize = {
  width: width,
  height: height
};

page.open('https://example.com/', function (status) {
  if (status !== 'success') {
    console.error('Unable to load page');
    phantom.exit(1);
    return;
  }

  // Capture exactly the viewport-sized rectangle.
  page.clipRect = {
    top: 0,
    left: 0,
    width: width,
    height: height
  };

  page.render('screenshot.png');
  phantom.exit();
});

The important detail is not the sample URL or the particular dimensions. It is the relationship between the two settings: the viewport controls page layout, while the clip rectangle controls the pixels copied into the output.

Run and verify the result

  1. Save the script as capture.js.
  2. Run it with your PhantomJS executable, for example phantomjs capture.js.
  3. Inspect screenshot.png with an image tool that reports pixel dimensions.
  4. Confirm that the reported width and height equal the clipRect width and height, subject to any image-processing step you apply afterward.

Assigning clipRect after page.render() is too late; the render call uses the settings that exist at the moment it runs. Likewise, setting the viewport only after page.open() can leave the page laid out at a different size than the one you intended.

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

Full-page capture: when a tall image is correct

For a full-page image, the content below the fold must remain in the capture. Do not force a viewport-sized clipRect, because that deliberately removes the rest of the page. Keep a suitable viewportSize for layout and use the rendering behavior appropriate to your PhantomJS script when you need the page’s complete vertical content.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Do not infer that a full-page image has a bug merely from its height. Compare the output with the page’s actual document length and your capture requirement. The defect is specifically a mismatch between the requested viewport-only output and the rectangle being rendered.

Systematic troubleshooting when the dimensions are still wrong

1. Print the values immediately before rendering

Log the variables used to construct both settings. A later callback, helper function, or conditional branch may be replacing the width or height. The values that matter are the ones present immediately before page.render().

console.log('viewport:', JSON.stringify(page.viewportSize));
console.log('clip:', JSON.stringify(page.clipRect));
page.render('screenshot.png');

For a viewport-only capture, check that clipRect.top and clipRect.left are zero and that its width and height match the intended viewport dimensions.

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

2. Check the load-status branch

Only render after page.open() reports success. Rendering a failed or partially loaded page can make the result look unrelated to the sizing problem. Keep the failure path separate and exit with a nonzero status, as in the example.

3. Confirm that the same page object is rendered

In larger scripts, it is possible to configure one page object and call render() on another. Keep creation, navigation, clipping and rendering together while diagnosing the issue. Also check whether a callback or utility function changes page.clipRect before the final call.

4. Look for a different frame or page state

If your script navigates again, switches frames, or captures after additional asynchronous work, make sure the final render still targets the document and page object whose dimensions you inspected. The available API guidance does not establish one universal secondary cause for every script, so these checks must be tied to your actual code.

5. Separate pixel dimensions from page layout

A page can have a 1024 × 768 layout viewport while containing a document much taller than 768 pixels. That is normal. The clip rectangle, not the document’s total height, determines the bounded screenshot. Conversely, CSS zoom, device scaling, or later image processing can change how the file is displayed or interpreted, so verify the raw image dimensions before diagnosing PhantomJS.

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

6. Make timing explicit

Some pages change their layout after the initial load because scripts insert content or resize components. If you intentionally wait for application code before capturing, assign the clip rectangle after that wait and immediately before render(). This does not replace the viewport setting; it ensures that your final capture bounds are not overwritten during the page’s setup.

Common mistakes and their fixes

Symptom Likely mistake Fix
Image is taller than the visible browser area viewportSize was set, but no matching clipRect was set Add a zero-origin clip rectangle with the target width and height
Image dimensions are unexpectedly small or shifted Clip rectangle has nonzero top or left, or uses stale variables Set top: 0, left: 0 and log the final values
Responsive layout is wrong even though the image size is right Viewport was assigned after navigation Assign page.viewportSize before page.open()
Output includes the entire page when only the fold was wanted Capture was left unbounded or configured for full-page output Use a viewport-sized clipRect
Output is blank or incomplete Script rendered after a failed load or before required page setup finished Check status, wait for the page’s required state, then render once

How to make the fix maintainable

Use one source of truth for dimensions

Store width and height in variables and use those variables for both properties. This prevents a viewport of one size from being paired with a clip rectangle of another size.

Keep capture intent visible

Name the routine according to its purpose, such as captureViewport or captureFullPage. A future maintainer can then see why a clip rectangle is present or intentionally absent.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Test more than one viewport

Run the same script at a desktop size and at a narrow mobile size. A correct implementation should produce files whose pixel dimensions match each supplied clip rectangle, while the page’s responsive layout changes according to each viewport.

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.

Do not use clipping to hide a layout defect

Clipping changes what is captured; it does not fix overflowing CSS, an incorrectly sized fixed element, or content inserted outside the intended layout. If the viewport-sized image shows a horizontal scrollbar or clipped component, inspect the page’s layout separately.

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

Or skip the browser setup

If you need a reliable URL-to-image request rather than a PhantomJS maintenance task, ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL and returns a PNG, JPEG, WebP or PDF. You can still choose a viewport and capture options without managing a headless-browser process.

One-call cURL request

See the ScreenshotNeo documentation for the current API parameters. This request saves a WebP image:

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

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(`Screenshot request failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Why this changes the operational work

  • Cookie and consent banners, newsletter popups and chat widgets are removed before the shot. Each cleanup step can be turned off when you need the original page state.
  • Bot checks or CAPTCHAs, blank pages, timeouts and failed loads are not billed. The response identifies the page verdict and billing result with X-Page-Verdict and X-Billed headers; cache hits are also not billed.
  • An MCP server supplies take_screenshot, get_page_info and capture_pdf tools to Claude, Cursor and other MCP clients.
  • The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots; yearly billing gives two months free, and every feature is available on every plan.

Sign up for ScreenshotNeo to use the free monthly allowance without a card.

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

Performance, reliability and cost considerations

A local PhantomJS script gives you direct control over the process, but you must manage the executable, page timing, failures and output storage yourself. A remote API shifts that browser setup to the service and can expose response headers that distinguish a clean billed capture from a failed or cached result. For either approach, avoid treating a timeout or blank page as a valid screenshot: check the process status or API response before publishing the file.

For repeated captures, keep the requested dimensions and capture intent explicit. A viewport screenshot should have a bounded rectangle; a full-page capture should be selected deliberately because its height depends on page content. If you use caching, choose a freshness policy appropriate to the page rather than assuming every request represents a new render.

Decision checklist

  • Do you want only what a user sees without scrolling? Set viewportSize and a matching zero-origin clipRect.
  • Do you need content below the fold? Use a full-page capture and expect a tall output.
  • Is the responsive layout wrong? Set the viewport before opening the page.
  • Is the file still wrong? Log the final rectangle, verify the load status, and confirm that the rendered page object is the configured one.
  • Do you want to avoid maintaining PhantomJS capture code? Use ScreenshotNeo’s API or MCP tools and validate its response headers.

Frequently Asked Questions

Does changing only page.viewportSize.height crop the screenshot?

No. It changes the browser’s layout viewport. Cropping is controlled separately by page.clipRect.

What should clipRect.top and clipRect.left be for a normal viewport screenshot?

Use zero for both so the capture starts at the viewport’s top-left corner.

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

Is a tall PhantomJS image always evidence of a bug?

No. A full-page capture is expected to be taller than the visible viewport because it includes content below the fold.

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
PC Slower Than It Used to Be?Free scan - under a minute

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.