ScreenshotNeo

BlogHTML to image & PDF

How to Remove Headers, Footers, and Gray Backgrounds from Headless Chrome PDFs

Remove Chrome PDF headers, footers, and unwanted gray backgrounds with current CLI flags, Puppeteer options, print CSS, and troubleshooting.

By the ScreenshotNeo team30 September 20268 min read

How to Remove Headers, Footers, and Gray Backgrounds from Headless Chrome PDFs

Chrome can add a date, page title, URL, and page number to PDFs generated in headless mode. A page can also appear gray because of print backgrounds, inherited CSS, shadows, or print color adjustment. The fix depends on whether the unwanted pixels come from Chromium’s generated print furniture or from the webpage itself.

For the current Chrome command line, add --no-pdf-header-footer:

chrome --headless --print-to-pdf=output.pdf --no-pdf-header-footer https://example.com

For Puppeteer, set displayHeaderFooter: false and control backgrounds with printBackground. Then inspect print-specific CSS and page sizing if gray regions, whitespace, clipping, or pagination remain. This guide separates each case and gives runnable CLI, Puppeteer, Python, Node.js, and ScreenshotNeo examples.

There are two different kinds of headers and footers:

  • Chromium-generated furniture: the date and time at the top, plus the page URL and page number at the bottom. Chrome adds these during PDF printing.
  • Page-authored content: an HTML <header>, <footer>, fixed navigation, consent bar, or other element rendered by the website.

The PDF header/footer option only controls the first kind. It cannot remove an element that belongs to the page DOM. That element needs print CSS, JavaScript, or a selector-specific hiding rule.

Gray output can have several causes:

  • A page background or panel background is being printed.
  • A parent element supplies a background that is not obvious from the target element.
  • Box shadows, opacity, overlays, or a fixed backdrop create a gray region.
  • Print media CSS changes colors.
  • Color adjustment preserves a gray value that screen rendering did not show.

Save a fresh PDF with the exact Chrome binary or Puppeteer version used in deployment. Your desktop browser may not be the browser producing the automated file.

2. Remove generated headers and footers with Chrome CLI

Use Chrome’s current documented switch together with --print-to-pdf:

Generated Chrome print furniture is removed at the browser PDF layer.
Generated Chrome print furniture is removed at the browser PDF layer.
chrome --headless \
  --print-to-pdf=output.pdf \
  --no-pdf-header-footer \
  https://example.com

Chrome documents that this omits the print header containing the current date and time and the footer containing the URL and page number. Chromium defines the switch as: “Do not display header and footer in the printed PDF file.” See the Chrome Headless mode documentation and the Chromium switch source.

Older Chrome spelling

Older releases used --print-to-pdf-no-header. If the current flag is reported as unknown, check the version of the binary actually launched by your script or container:

chrome --version
chromium --version

Use the spelling supported by that installed build, then plan a browser upgrade when practical. Do not try to solve an unrecognized command-line switch with CSS; the browser has not reached page rendering yet.

CLI details that affect the result

  • Put the output path after --print-to-pdf=.
  • Use the same executable in local and CI environments when comparing files.
  • Quote URLs containing shell metacharacters.
  • Keep the header/footer switch in the command that creates the PDF; passing it to a wrapper that never forwards unknown flags has no effect.

3. Remove generated headers and footers with Puppeteer

Puppeteer’s page.pdf() API controls Chromium PDF printing. Set displayHeaderFooter: false explicitly, even though the documented default is already false:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'networkidle0' });

await page.pdf({
  path: 'output.pdf',
  displayHeaderFooter: false
});

await browser.close();

If you need a custom running header or footer, set displayHeaderFooter: true and provide headerTemplate and footerTemplate. Puppeteer supports template classes such as date, title, url, pageNumber, and totalPages. Removing the generated furniture and creating a custom template are mutually different configurations.

Puppeteer generates PDFs with the print CSS media type. The Page.pdf() reference documents this behavior and the PDF options discussed here.

4. Control gray backgrounds with Puppeteer options

printBackground controls whether CSS background graphics are printed. Its documented default is false. Make the setting explicit while diagnosing a gray page:

Print CSS can remove one gray overlay while preserving important chart colors.
Print CSS can remove one gray overlay while preserving important chart colors.
await page.pdf({
  path: 'output.pdf',
  displayHeaderFooter: false,
  printBackground: false
});

If the document requires colored charts or branded panels, leave backgrounds enabled and remove only the unwanted region with print CSS:

await page.addStyleTag({
  content: `
    @media print {
      .unwanted-panel,
      .cookie-banner,
      .chat-widget-backdrop {
        background: transparent !important;
        box-shadow: none !important;
      }
    }
  `
});

await page.pdf({
  path: 'output.pdf',
  displayHeaderFooter: false,
  printBackground: true
});

Use the actual selectors from the target page. A gray area may belong to a parent, pseudo-element, fixed overlay, or backdrop rather than the element that visually appears gray.

Use print color adjustment selectively

Chrome can modify colors for printing. Puppeteer documents the prefixed property -webkit-print-color-adjust for forcing exact colors. Apply it only to elements that need color fidelity:

@media print {
  .chart,
  .brand-color {
    -webkit-print-color-adjust: exact;
  }

  .unwanted-panel {
    background: white !important;
    color: black !important;
    box-shadow: none !important;
  }
}

Applying exact color adjustment to the entire document can preserve an unwanted gray background. Scope the rule to charts, logos, or other regions where color matters.

5. Hide page-authored headers, footers, and overlays

When the unwanted content is in the page DOM, use a print-only override. For example:

@media print {
  header.site-header,
  footer.site-footer,
  .sticky-toolbar,
  .newsletter-modal,
  .chat-launcher {
    display: none !important;
  }

  body {
    background: white !important;
  }
}

Inject this CSS from Puppeteer when you cannot modify the source application:

await page.addStyleTag({
  content: `
    @media print {
      header.site-header,
      footer.site-footer,
      .sticky-toolbar,
      .newsletter-modal,
      .chat-launcher {
        display: none !important;
      }
      body { background: white !important; }
    }
  `
});

For a site you control, prefer a maintained print stylesheet. Removing a fixed element can expose content that was previously padded below it, so inspect the first and last page after the change.

6. Fix whitespace, clipping, and page-size changes

Removing headers and footers changes the printable area. If content is clipped or pagination changes, inspect CSS @page rules, API margins, and paper format together.

@page {
  size: A4;
  margin: 12mm;
}
await page.pdf({
  path: 'output.pdf',
  displayHeaderFooter: false,
  format: 'A4',
  margin: {
    top: '12mm',
    right: '12mm',
    bottom: '12mm',
    left: '12mm'
  },
  preferCSSPageSize: true
});

preferCSSPageSize defaults to false. With that default, configured format, width, or height takes priority and CSS page sizing may be scaled to fit. Set it to true when the document’s @page size should win. Avoid treating @page { margin: 0 } as a universal header-removal technique: it changes content space and can cause clipping.

7. Complete Puppeteer example

This example makes the relevant choices explicit and removes a page-authored overlay while preserving backgrounds elsewhere:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch({ headless: true });
const page = await browser.newPage();

await page.goto('https://example.com', {
  waitUntil: 'networkidle0',
  timeout: 60000
});

await page.addStyleTag({
  content: `
    @media print {
      .cookie-banner,
      .chat-widget,
      .newsletter-modal {
        display: none !important;
      }
      .unwanted-panel {
        background: transparent !important;
        box-shadow: none !important;
      }
    }
  `
});

await page.pdf({
  path: 'clean.pdf',
  format: 'A4',
  displayHeaderFooter: false,
  printBackground: true,
  preferCSSPageSize: true,
  margin: {
    top: '12mm',
    right: '12mm',
    bottom: '12mm',
    left: '12mm'
  }
});

await browser.close();

8. Equivalent automation from Python

Python can launch Chrome directly with the same current flag:

import subprocess

subprocess.run([
    'google-chrome',
    '--headless',
    '--print-to-pdf=output.pdf',
    '--no-pdf-header-footer',
    'https://example.com',
], check=True)

If your Python project already uses browser automation, configure its Chromium wrapper so that the generated PDF receives the equivalent displayHeaderFooter, printBackground, and margin settings. Verify the wrapper’s installed browser version rather than assuming it matches system Chrome.

9. Troubleshooting checklist

Symptom Likely cause Fix
Date, URL, or page numbers remain CLI flag missing, unsupported, or not forwarded Use --no-pdf-header-footer; check the actual Chrome version. Try the older spelling only for older builds.
The website’s own header remains It is page DOM content Hide its selector with @media print CSS or injected styles.
Gray block remains with printBackground: false Inherited background, shadow, opacity, pseudo-element, or overlay Inspect computed print styles and override the responsible selector, parent, or pseudo-element.
Charts lose their colors Background printing disabled or print color adjustment Enable printBackground and apply -webkit-print-color-adjust: exact only to the chart.
Content is clipped after cleanup Margins, @page size, or fixed elements changed the layout Compare PDF margins with CSS margins; use preferCSSPageSize deliberately.
Blank or incomplete PDF Capture happened before content loaded Wait for the required selector, network idle, fonts, and client-side rendering before calling PDF.
Local result differs from CI Different Chrome or Puppeteer version Log the deployed binary version and test in the same container or image.

10. Performance, reliability, and cost considerations

PDF rendering waits on page loading, layout, fonts, images, and any JavaScript your workflow chooses to wait for. A network-idle wait can be slow on pages with analytics or long-lived connections. Prefer a meaningful readiness selector when the application provides one, and use a bounded timeout.

Reuse a browser process for batches of PDFs, but create an isolated page per job. Close pages after capture and monitor memory for very long documents. Full-page pages with large images consume more memory than a viewport-sized capture. Keep CSS overrides narrowly scoped so they do not trigger unexpected layout changes.

Cache stable inputs when appropriate, and record the Chrome and Puppeteer versions alongside generated files. This makes changes in pagination or color behavior easier to explain. No official documentation in the supplied research publishes a universal rendering benchmark, so performance depends on the page, resources, browser build, and deployment environment.

11. Or skip the browser setup

ScreenshotNeo provides a website screenshot and PDF API. One GET request returns a PNG, JPEG, WebP, or PDF, so you do not need to maintain a Chrome process for this workflow. Its capture options include PDF paper size, margins, landscape mode, and page ranges, plus custom CSS and JavaScript when a page needs print-specific cleanup. Read the ScreenshotNeo API documentation for the complete option list.

cURL:

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)
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}`);

Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed; response headers identify the page verdict and whether the request was billed. ScreenshotNeo also provides an MCP server so Claude, Cursor, and other MCP clients can take screenshots, inspect pages, and capture PDFs. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 shots.

Create a free ScreenshotNeo account and start with the 1,000-shot monthly allowance.

12. FAQ

No. It controls Chromium’s generated print furniture. Hide an HTML footer with print CSS or JavaScript.

Should I always set printBackground to false?

No. Use false to remove unwanted page backgrounds, but enable it when the PDF must preserve charts, branded panels, or background images. Override only the unwanted selector when possible.

Why did removing the header change page breaks?

The printable area changed. Check PDF margins, CSS @page margins, paper format, and preferCSSPageSize.

Which Chrome flag should new automation use?

Use --no-pdf-header-footer with current Chrome. Treat --print-to-pdf-no-header as an older-version compatibility spelling.

Can CSS remove Chrome’s generated date and URL?

Use the browser option or CLI switch. CSS controls page content and print layout, not Chromium’s generated header/footer furniture.