ScreenshotNeo

BlogHow-to

How to Capture a Website Screenshot Without Duplicating Sticky Elements

Use Playwright screenshot-time CSS to hide or restyle sticky UI before a full-page capture. Learn Firefox options, troubleshooting, and when to capture one element instead.

By the ScreenshotNeo team4 October 20266 min read

To prevent a sticky header, fixed toolbar, or floating control from appearing repeatedly in an automated full-page screenshot, apply screenshot-time CSS to that specific element and capture with Playwright’s fullPage: true. Hide it if it is not needed, or restyle its positioning if it should appear once. The right selector and treatment depend on the page, so inspect the result. Playwright documents both full-page capture and screenshot-time styles; it does not promise identical sticky-element behavior on every page or browser. Playwright Page API.

Why sticky elements can show up more than once

A sticky element participates in normal positioning until it reaches a specified inset, such as top: 0, then sticks within its relevant scroll area. A fixed element can remain at the same position relative to the viewport as the page scrolls. Those behaviors can interact with how a particular browser or capture engine builds a full-page image. Repetition is not guaranteed across all pages or screenshot methods, so inspect the actual output. MDN’s position reference.

First decide what the finished image should show:

  • Omit persistent UI: hide the specific header or control during capture.
  • Show the header once: adjust its positioning for the capture, then check whether the change affects page layout.
  • Capture a component only: take an element screenshot instead of a full-page image.

Automated capture with Playwright

Install Playwright and its Chromium browser, save the following as capture.mjs, then run node capture.mjs https://example.com. Replace header.site-header with a selector that matches the sticky element on your page.

import { chromium } from 'playwright';

const target = process.argv[2];
if (!target) {
  throw new Error('Usage: node capture.mjs https://example.com');
}

const browser = await chromium.launch();
try {
  const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });
  await page.goto(target, { waitUntil: 'networkidle', timeout: 60_000 });
  await page.screenshot({
    path: 'page.png',
    fullPage: true,
    style: `header.site-header { display: none !important; }`,
  });
} finally {
  await browser.close();
}

The screenshot style option applies CSS while the screenshot is taken. Playwright documents that it pierces Shadow DOM and applies to inner frames. The selector above is illustrative, not universal. If the element should appear once, try changing its positioning instead of hiding it, and verify the page’s layout in the output. The style option was added in Playwright v1.41, so use a version that supports it. See the Playwright Page API.

Find and target the right element

  1. Open the page in browser developer tools and inspect the header or control.
  2. Identify a stable selector, preferably a page-specific class or an ID rather than a broad selector such as header.
  3. Check whether the element is sticky, fixed, or inside a nested scroll area; inspect its computed styles and ancestors.
  4. Apply a narrowly scoped screenshot style and capture again.
  5. Review the full output at the top, middle, and bottom. Confirm that important content was not hidden along with the persistent UI.

For example, if the page uses #global-nav, the style could be #global-nav { display: none !important; }. Avoid hiding every position: fixed element automatically: that can remove useful content such as a consent choice, video controls, or a page-specific panel.

Capture one element instead

If the goal is a card, chart, or section rather than a tall document, use Playwright’s locator screenshot so the sticky page chrome is outside the capture:

const card = page.locator('.product-card').first();
await card.screenshot({ path: 'product-card.png' });

Use a selector that uniquely identifies the intended node. If multiple matches exist, choose the right one explicitly, as above. See the locator screenshot options in the Playwright API.

Manual capture in Firefox

Firefox Developer Tools can capture the entire page or a single node. For a full-page capture, use the screenshot control in Developer Tools. If it is not visible, enable “Take a screenshot of the entire page” under Settings > Available Toolbox Buttons. For one element, right-click its node in the Inspector’s HTML pane and choose “Screenshot Node.”

The Web Console also provides a screenshot helper. Use :screenshot --fullpage for the page outside the visible window, or :screenshot --selector .product-card to capture a selected element and its descendants. Consult Firefox’s screenshot documentation for the documented workflow and options.

Choose the capture that fits the result

Need Approach Check
A tall image of the document Playwright full-page screenshot or Firefox full-page screenshot Whether persistent UI repeats or obscures content
A clean page without persistent controls Full-page capture with narrowly scoped screenshot CSS That the selector matches only the intended element
A header shown once Restyle its position during capture That changing positioning has not shifted or overlapped content
A single component Playwright locator screenshot or Firefox Screenshot Node That the chosen node includes the required content
A repeatable scripted workflow Playwright with explicit viewport, selector, and readiness handling That page state and timing are consistent between runs

Troubleshooting

Symptom Likely cause Fix
The sticky header still appears The selector does not match, the element is in a frame or shadow tree with different markup, or another header is responsible Inspect the rendered element and use its actual selector. Playwright’s screenshot-time style reaches Shadow DOM and inner frames, but the selector still needs to match.
Content disappears with the header The selector is too broad or matches multiple elements Use a more specific page-level selector and inspect the page after applying the style.
The header is missing entirely The style hides it when the intended result was to show it once Restyle positioning instead of using display: none; validate layout and overlap in the resulting image.
The screenshot is only the viewport fullPage was omitted or set to false Set fullPage: true for a full scrollable-page capture.
Firefox has no full-page screenshot button The toolbox button is disabled Enable “Take a screenshot of the entire page” in Settings > Available Toolbox Buttons.
The capture times out or looks incomplete The page is slow, keeps network activity open, or renders content after navigation Adjust the navigation readiness condition or timeout for the site, wait for a meaningful selector, and verify lazy-loaded content before capture.
Images lower on the page are blank Lazy-loaded assets may not have loaded before the screenshot Scroll through the page or wait for the relevant images to load before capturing, then inspect the output.

Performance, reliability, and cost

Full-page screenshots can take longer and use more memory than viewport or element screenshots because they cover more page content. Large pages, complex layouts, and image-heavy sites increase the work. Capture only the region you need when a full-page image is unnecessary.

For repeatability, keep the viewport and target selector explicit, wait for the content that matters, and review output after changes to the page or stylesheet. Network-idle waiting can be unsuitable for pages that keep connections open; use a page-specific readiness condition when necessary. The research sources document capture features but provide no cross-browser benchmark or universal guarantee for sticky behavior.

With a self-hosted Playwright workflow, account for the time and compute needed to run the browser and store the resulting files. There is no single cost figure for this setup; it depends on where and how often it runs.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF; see the API documentation. Example request:

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

ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers indicate the page verdict and billing status. Its MCP server includes take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.

Sign up for 1,000 free screenshots a month, with no card required.

FAQ

Does fullPage: true automatically remove sticky headers?

No. It requests a full scrollable-page screenshot. Apply a targeted screenshot style if persistent UI should be hidden or changed.

Can I use a generic selector such as header?

You can, but it may match more than the sticky site header. Inspect the page and prefer a selector specific to the element you intend to change.

Should a sticky header be hidden or repositioned?

Hide it when it adds no value to the image. Reposition it when it should appear once, and check that the change preserves the intended layout.

Is a full-page screenshot always the best choice?

No. For one component, a node or locator screenshot avoids capturing unrelated page content.