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.

If PhantomJS screenshots show SVG text but omit a rectangle’s border, there is no confirmed one-line fix for the reported case. First verify that the <rect> is actually painted in the page, then check page loading, JavaScript errors, and capture bounds. The specific report describes a transparent-filled rectangle with a blue stroke and stroke-dasharray="0" on PhantomJS 1.8 through 2.1, but does not include a verified answer. Treat renderer bugs as a possibility only after ruling out document and capture conditions.

What can make an SVG rectangle disappear?

An SVG <rect> is a renderable element, but that does not guarantee that it will be visible in a screenshot. Its rendering depends on the document state, computed styles, geometry, paint order, clipping, and the area selected for capture. The W3C SVG 2 rendering model describes which elements can be rendered and gives examples of elements that are not painted, including elements excluded by conditional processing, elements with display:none, and descendants of non-rendered elements: SVG 2 rendering model.

The reported question says text remained visible while blue borders around SVG rectangles did not. The rectangle was described as having fill="transparent", a blue stroke, and stroke-dasharray="0". The report covers PhantomJS 1.8 through 2.1 and has no confirmed fix in the available question page: original Stack Overflow question. Because the exact cause is not established, do not assume that changing one attribute will solve every similar failure.

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.

Separate “not painted” from “not captured”

If the rectangle is outside the page viewport or outside an explicitly selected capture rectangle, the screenshot will not contain it even if the browser rendered it correctly. PhantomJS documents clipRect as the page portion to capture: screen-capture documentation. If the rectangle is within the captured area but absent, inspect SVG state and style before blaming capture bounds.

Check the SVG element and its computed style

Inspect the affected rectangle in the same page state PhantomJS captures. Confirm that the node exists, that its dimensions and coordinates are nonzero and in range, and that the computed style permits painting. An SVG attribute in the source is not enough to establish the final computed value: CSS rules, inherited values, scripts, and conditional state can change what is rendered.

Verify visibility, geometry, and stroke

  • Confirm the element is present in the DOM at capture time, and that its parent SVG and ancestors are rendered.
  • Check computed display and visibility. display:none removes the element from rendering; visibility:hidden prevents it from being painted, though it has a different role in the rendering tree.
  • Check x, y, width, and height. A zero width or height, or a rectangle positioned beyond the SVG viewport, may yield no visible border.
  • Check stroke and stroke-width after CSS is applied. A transparent stroke, zero width, or a color matching the background can look like a missing border.
  • Inspect stroke-dasharray. The reported case uses stroke-dasharray="0"; test a simple solid stroke by removing the attribute or setting stroke-dasharray="none" in a controlled copy. This is a diagnostic comparison, not a proven patch for the report.
  • Check paint order, masks, filters, clipping paths, and overlapping elements. A later opaque element can cover a border that was painted correctly.

Use the browser’s DOM inspector or temporary page-side logging to compare the SVG attributes with computed style. A minimal test should use a plain SVG with one rectangle and a contrasting solid stroke, then add the original styles and surrounding elements one at a time. This helps distinguish an attribute or stylesheet interaction from an environment issue.

Confirm the PhantomJS binary and page state

PhantomJS is an older headless browser, so establish exactly which executable and version your script invokes before comparing results. The project homepage identifies QtWebKit as its backend and states that development is suspended: PhantomJS project homepage. Its documentation demonstrates SVG screen capture, which indicates general SVG support but does not establish that every feature or legacy rendering case works correctly.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. Check the executable: run phantomjs --version in the same environment that runs the capture job. If the command is not found, invoke the installed binary by its full path or correct the environment’s PATH.
  2. Make a minimal page: save a local HTML file containing the affected SVG, with no application framework or external assets. Capture that page using the same PhantomJS binary.
  3. Wait for page loading: ensure your capture code runs after the page and required resources load. If application code inserts the SVG asynchronously, an immediate screenshot may precede that update.
  4. Log JavaScript errors: attach a page.onError handler and check the console output. A script exception can prevent the app from reaching the state in which it paints the rectangle. PhantomJS troubleshooting guidance describes debugging and error reporting: troubleshooting documentation.
  5. Compare with a current browser: render the same file at the same viewport in a current browser. Keep the SVG, styles, and page state constant so that differences point to the rendering environment rather than an unrelated change.

Minimal PhantomJS capture script

Save the following as capture.js. It logs load failures and page JavaScript errors, sets a viewport, and captures a local HTML file after its load event. Substitute the actual absolute file URL for file:///absolute/path/to/test.html, or use your page URL.

var page = require('webpage').create();
page.viewportSize = { width: 1200, height: 900 };
page.onError = function (message, trace) {
  console.error('Page error: ' + message);
  trace.forEach(function (item) {
    console.error('  ' + item.file + ':' + item.line);
  });
};
page.onResourceError = function (resourceError) {
  console.error('Resource error: ' + resourceError.url + ' — ' + resourceError.errorString);
};
page.onLoadFinished = function (status) {
  console.log('Load status: ' + status);
  window.setTimeout(function () {
    page.render('phantomjs-test.png');
    phantom.exit(status === 'success' ? 0 : 1);
  }, 500);
};
page.open('file:///absolute/path/to/test.html');

Run it with phantomjs capture.js. The 500 ms delay is merely a small diagnostic wait for simple pages; it is not a universal guarantee that an application has finished drawing. For an app that renders asynchronously, wait for a page-specific condition instead of relying on an arbitrary delay.

Check viewport and clipping bounds

PhantomJS screenshots can be cropped by capture settings. Compare the rectangle’s actual page position and bounds with the viewport and any clipRect configured in your script. In a diagnostic run, remove clipping and render the full page; then reintroduce the clip only after confirming its coordinates and size. When comparing full-page output with bounded output, leave the document and viewport unchanged so that the crop is the only changed variable.

For an SVG with a viewBox, also check the relationship between its coordinate system and rendered width and height. An element can exist at valid SVG coordinates but lie outside the visible viewBox. Clipping may also come from an SVG <clipPath> or CSS, not just PhantomJS’s screenshot setting.

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

Isolate the cause with controlled comparisons

Change one variable per capture and save each result. This avoids treating correlation as a fix and makes legacy rendering behavior easier to identify.

  1. Capture a minimal inline SVG with one rectangle, a solid contrasting stroke, no external CSS, and no clipping or masks.
  2. Add the original fill, stroke, and dash settings, one at a time. In particular, compare the reported stroke-dasharray="0" with a solid stroke.
  3. Add the surrounding SVG and styles, then the rest of the HTML page. Watch for ancestor visibility, overlap, masks, and clipping.
  4. Compare a capture immediately after load with one after the app’s SVG-population condition is met.
  5. Compare PhantomJS and a current browser using the same page state, viewport, and crop.
  6. Compare a full-page capture with the same page captured through an explicit clipRect.

If the minimal case works but the production page fails, focus on page state, styles, resources, and bounds. If a minimal SVG still differs between PhantomJS and a current browser after those checks, a legacy renderer limitation is plausible. PhantomJS’s suspended development makes that possibility worth considering, but it does not prove the cause of this particular missing border.

Troubleshooting by symptom

Symptom Likely area to inspect Next check
SVG text appears but rectangle border does not Rectangle geometry, computed stroke, dash style, paint order, or clipping Test one rectangle with a solid contrasting stroke and no surrounding styles.
Rectangle is missing only in PhantomJS Legacy renderer behavior or a difference in page timing Compare identical minimal SVG output in PhantomJS and a current browser.
Rectangle appears only when waiting Application populates or styles the SVG asynchronously Wait for the specific element or app-ready condition before rendering.
Rectangle disappears with clipping enabled clipRect coordinates or dimensions Render without the clip, then correct the bounds against the element’s page position.
Local test works but live page fails External resources, runtime errors, dynamic state, or page-specific CSS Review resource errors and page.onError output; simplify the live page incrementally.
Capture exits or produces no expected file Script path, PhantomJS invocation, page-open failure, or output permissions Check the command’s exit status and logs, then verify the output directory is writable.
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 your goal is a clean capture of a page rather than diagnosing this particular PhantomJS renderer, ScreenshotNeo offers a one-request screenshot API. It is not a fix for a malformed or hidden SVG, but it can avoid maintaining a PhantomJS browser setup for routine captures. The API accepts a URL and returns an image or PDF; see the ScreenshotNeo site and API documentation.

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

ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for the free plan.

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

When to stop debugging PhantomJS

Keep PhantomJS in the workflow only if its output is acceptable for the page and rendering features you need. Its project homepage says development is suspended, so do not assume an issue in an old QtWebKit-based rendering path will receive a future correction. When a minimal case reproduces only in PhantomJS, record the exact binary version, minimal SVG, viewport, capture settings, and output difference; that is a useful, reproducible diagnosis even when no verified patch is available.

Frequently Asked Questions

Does setting stroke-dasharray="none" definitely fix the reported issue?

No. It is a useful controlled test because the reported rectangle used stroke-dasharray="0", but the original report has no confirmed solution.

Is SVG <rect> unsupported by PhantomJS?

No broad lack of SVG support is established. PhantomJS’s screen-capture documentation demonstrates SVG rendering, but that does not guarantee correct handling of every SVG feature or legacy edge case.

Should I switch renderers if the minimal SVG still fails?

If the same minimal file renders differently in PhantomJS and a current browser after state, style, loading, and bounds have been checked, treating it as a likely legacy renderer limitation is reasonable; it is not proof of a specific defect.

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.