ScreenshotNeo

BlogHow-to

How to screenshot a web page with sticky headers without repeating them

Use Playwright’s screenshot-only CSS to hide or reposition sticky headers in full-page captures. Includes Firefox and Puppeteer options, troubleshooting, and an API shortcut.

By the ScreenshotNeo team4 October 20267 min read

A full-page screenshot includes the page’s scrollable content; it does not automatically omit sticky or fixed headers. For repeatable captures, use Playwright’s screenshot-time style option with a selector confirmed on the page. Hide the header if its content is not needed, or test a positioning override if you need one visible instance. The right selector and whether an override preserves the layout are site-specific, so inspect the result.

Playwright describes a full-page screenshot as a capture of the “full scrollable page, as if you had a very tall screen and the page could fit it entirely.” Playwright’s Screenshots documentation covers full-page and element screenshots.

Use Playwright to prevent repeated sticky headers

Playwright’s screenshot API supports a stylesheet applied only for the screenshot. Its documented use cases include hiding dynamic elements or changing their properties. The injected style also applies inside Shadow DOM and inner frames. That gives you a repeatable way to adjust the header without changing the site’s source files.

Runnable JavaScript example

Install Playwright and its Chromium browser, then save this as capture.mjs. Replace the URL and selector with the target page and the header selector you verified in that page’s DOM.

npm install playwright
npx playwright install chromium

// capture.mjs
import { chromium } from 'playwright';

const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });

try {
  await page.goto('https://example.com', { waitUntil: 'networkidle', timeout: 60000 });
  await page.screenshot({
    path: 'page.png',
    fullPage: true,
    style: 'header.site-header { display: none !important; }',
    animations: 'disabled',
  });
} finally {
  await browser.close();
}

The selector header.site-header is an example, not a universal rule. Inspect the target page and use a narrow selector; a broad rule such as header may remove content sections that are not sticky navigation. See the Playwright Page API for screenshot options.

Keep one header instance instead of hiding it

If the header contains information readers need, test changing its positioning in the screenshot stylesheet. For example, a site may respond to an override like:

style: 'header.site-header { position: static !important; top: auto !important; }'

This is a starting point, not a guaranteed fix. Sticky behavior may come from another selector or ancestor, and changing positioning can affect spacing, overlap, or the layout near the top. Capture, inspect, and adjust the CSS for the particular page.

Step-by-step workflow

  1. Find the actual header element. Inspect the page in browser developer tools. Confirm which element is sticky or fixed and choose a selector specific enough not to match unrelated content.
  2. Decide whether the header’s content belongs in the image. Hide it when it is repeated navigation with no value in the capture. If the content matters, try a screenshot-only positioning change and check the top of the page.
  3. Wait for the page to be ready. Choose a navigation wait condition that suits the site. networkidle can be useful for mostly static pages; pages with persistent network activity may need domcontentloaded followed by a targeted wait, or a deliberate delay.
  4. Capture the full page with the override. Use fullPage: true and the screenshot-time style property.
  5. Review the output. Check that the header appears the intended number of times, that meaningful page content remains, and that lazy-loaded or dynamic content is present. Refine the selector, readiness wait, or CSS and recapture as needed.

Choose a capture method

Method Best fit Header control Trade-off
ScreenshotNeo API or MCP-based screenshot workflows Provides capture options including custom CSS; inspect the output for the target page Requires an API key for API calls
Playwright Automated, repeatable browser captures Screenshot-time stylesheet can hide an element or change its properties Requires a script and a site-specific selector
Firefox Developer Tools Manual one-off captures Can capture a full page or selected element; the documented workflow does not say it automatically suppresses sticky headers Convenient without a script, but inspect the result
Puppeteer Captures already automated in Puppeteer Supports full-page screenshots and clipping; the reviewed screenshot options reference does not document screenshot-time stylesheet injection For this particular CSS adjustment, the documented Playwright route is more direct

Manual and other browser automation options

Firefox Developer Tools

Firefox Developer Tools can take a full-page screenshot or capture a selected element. Its Web Console :screenshot helper accepts --fullpage for the whole page and --selector for a selected element. The documented instructions explain how to enable the full-page screenshot button in toolbox settings. They do not describe a setting that automatically removes sticky headers, so check the resulting image and use a scripted stylesheet workflow if you need repeatable CSS control. See Mozilla’s Firefox screenshot documentation.

Puppeteer

Puppeteer’s screenshot options include fullPage, clip, and image format settings. Use it when your existing capture workflow is built on Puppeteer, but do not assume those options alone prevent sticky headers from appearing repeatedly. The Puppeteer ScreenshotOptions reference documents these screenshot options; the reviewed reference does not list a screenshot-time stylesheet override.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request can return a PNG, JPEG, WebP, or PDF. Its custom CSS option can be used to adjust a page for capture; choose a selector for the target site and review the result. See the ScreenshotNeo 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

Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot, and each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing; response headers report the page verdict and billing status. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.

Options and edge cases

  • Full page or one element: fullPage: true captures the scrollable page. For a focused capture, Playwright also supports element screenshots; this can avoid unrelated page sections, but does not itself fix a repeated header if the selected element contains one.
  • Hide versus reposition: hiding is predictable when navigation is irrelevant. Repositioning can retain header content once, but may change layout. Verify the output rather than assuming a CSS rule generalizes.
  • Lazy and dynamic content: full-page capture does not guarantee every lazy image or asynchronously rendered block has loaded. Scroll or wait for the specific content before capture when needed. Avoid relying on one arbitrary delay if a selector or page condition is available.
  • Frames and Shadow DOM: Playwright documents that screenshot styles pierce Shadow DOM and apply to inner frames. The selector still needs to correspond to the element you intend to change.
  • Animations: disabling animations can make repeat captures more consistent. It does not replace waiting for data or images to load.
  • Large pages: very long pages require more memory and can produce large image files. Capture a specific element or viewport when a full-page image is not required.

Troubleshooting

Symptom Likely cause Fix
The header still repeats The selector misses the sticky element, or another element implements the sticky bar Inspect the rendered DOM and computed styles; target the actual sticky element and recapture.
Other page content disappears The selector is too broad, such as header or a shared container Use a more specific selector and review the full output for missing content.
The header disappears but leaves an awkward gap Hiding the element does not necessarily remove spacing reserved by a wrapper or layout Inspect the wrapper and layout. Adjust only the necessary screenshot CSS, or test a static-position override.
The repositioned header overlaps the first section The site’s layout depends on sticky positioning, offsets, or a spacer Review the top of the capture, then adjust the relevant positioning or spacing for that page. If reliable placement is not possible, hide the header.
The image is blank or missing later sections Capture began before navigation, data rendering, or lazy loading completed Wait for a meaningful selector or page condition; for lazy content, trigger loading before taking the screenshot.
networkidle never arrives The page maintains long-lived requests or background polling Use a different navigation condition such as domcontentloaded, then wait for a specific element or a bounded delay.
Screenshot call fails on a huge page Full-page image dimensions or browser memory requirements exceed what the capture can handle Reduce viewport width if appropriate, capture sections or a selected element, or avoid full-page mode for that page.

Performance, reliability, and cost

For a local Playwright script, capture cost is the time and compute required to launch the browser, load the page, wait for content, and encode the image. Full-page captures of long pages take more resources than viewport or element captures. Reuse a browser process for batches of pages where appropriate, close pages and browsers in cleanup code, set timeouts, and make readiness waits specific to the target site.

Repeatability depends on the page as well as the script: dynamic content, ads, consent state, animation, and changing page structure can change output. Keep selectors narrow, control waits, and inspect captures after site changes. For a screenshot API, account for the service’s plan and request options; ScreenshotNeo’s published plan amounts are 1,000 free monthly shots, Starter $5 for 3,000, 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. Its billing rules exclude bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits.

Frequently asked questions

Does full-page mode automatically remove sticky headers?

No. Full-page mode captures scrollable page content. Use a confirmed selector and screenshot-time CSS when you want to hide or adjust a sticky element.

Can I keep the header visible once?

Often you can try changing its screenshot-time positioning, but the result depends on the site’s layout. Inspect the top of the capture for overlap or missing space.

Is there a universal selector for sticky headers?

No. Sites use different markup and styles. Inspect the particular page and select the element that actually sticks.

Can Firefox take a full-page screenshot?

Yes. Firefox Developer Tools documents full-page and selected-element screenshots. Its cited instructions do not specify automatic sticky-header removal.