ScreenshotNeo

BlogHow-to

How to Emulate Print and Screen Media with Puppeteer

Use Puppeteer to switch between print and screen CSS, check the active media type, and create PDFs with the intended styles.

By the ScreenshotNeo team4 October 20266 min read

Use Puppeteer’s page.emulateMediaType() to choose which CSS media rules apply: pass 'print' to apply @media print, 'screen' to apply @media screen, or null to clear the CSS media emulation. Puppeteer’s page.pdf() uses print media by default; select screen first if you want screen styling in the PDF.

await page.emulateMediaType('print');
await page.emulateMediaType('screen');
await page.emulateMediaType(null); // clear CSS media emulation

1. What media emulation changes

Media type emulation changes the page’s CSS media type. It lets you preview or capture the rules a site defines in @media print or @media screen. For example, a site may hide navigation and simplify colors for print while preserving its usual layout for screen.

The call does not send a document to a physical printer. It changes the CSS environment in the browser page. To create a PDF, use page.pdf().

2. Runnable Puppeteer example

Install Puppeteer in a Node.js project with npm install puppeteer. Save this as media-example.mjs and run it with node media-example.mjs. The script navigates to a page, switches media types, checks the active match, writes print- and screen-styled PDFs, then clears the override.

import puppeteer from 'puppeteer';

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

  await page.emulateMediaType('print');
  const printMatches = await page.evaluate(() => matchMedia('print').matches);
  console.log({ printMatches });
  await page.pdf({ path: 'print.pdf' });

  await page.emulateMediaType('screen');
  const screenMatches = await page.evaluate(() => matchMedia('screen').matches);
  console.log({ screenMatches });
  await page.pdf({ path: 'screen.pdf' });

  await page.emulateMediaType(null);
} finally {
  await browser.close();
}

The Puppeteer API returns a promise, so await the call before inspecting page state or generating the output. The matchMedia() checks show whether the selected media query matches in the page context. See the Puppeteer Page.emulateMediaType reference and Page.pdf reference.

3. Select print or screen CSS for a PDF

Puppeteer’s PDF generation uses print CSS by default. For print styling, call page.pdf() directly or explicitly select print. For screen styling, select screen before generating the PDF:

await page.emulateMediaType('screen');
await page.pdf({ path: 'screen-styled.pdf' });

To preview print-specific rules without creating a PDF, select print and inspect the page or evaluate a relevant style. Switching back with page.emulateMediaType('screen') selects screen explicitly; passing null disables CSS media emulation.

Need API What it controls
Apply print or screen CSS page.emulateMediaType('print') or ('screen') CSS media type
Clear media type emulation page.emulateMediaType(null) Disables CSS media emulation
Set dark mode or reduced motion page.emulateMediaFeatures([...]) Media feature values, such as prefers-color-scheme and prefers-reduced-motion
Change device viewport and user agent page.emulate(device) Device metrics and user agent
Create a PDF page.pdf() PDF output; print media by default

These controls are separate. Choosing 'screen' does not emulate a phone, and device emulation does not select print CSS. If you need a specific viewport or user agent, configure device emulation separately. Puppeteer recommends doing device emulation before navigation because some sites do not expect viewport changes after they load. For media features, see the emulateMediaFeatures reference and emulate reference.

5. Print styling and PDF details

Print styles often remove backgrounds, navigation, or interactive controls and adjust layout for paper. Browser PDF output also adjusts colors for printing by default. If exact CSS colors matter, Puppeteer’s PDF documentation points to -webkit-print-color-adjust. The final appearance can still depend on browser behavior and the document’s CSS, so inspect the generated PDF for the result you need.

/* Example page CSS when print colors should be preserved */
@media print {
  body {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }
}

Media selection only chooses which applicable CSS rules are used. It does not guarantee that a site’s print stylesheet is complete or that its screen layout will fit a paper page. Check page breaks, backgrounds, colors, and content visibility in the resulting PDF.

6. Troubleshooting

Symptom Likely cause Fix
The page still looks screen-styled in the print capture The media switch was not awaited, or the page has no relevant print rules. Await page.emulateMediaType('print') before reading state or capturing; verify with matchMedia('print').matches.
The PDF uses print layout when screen layout was expected page.pdf() uses print media by default. Call and await page.emulateMediaType('screen') before page.pdf().
matchMedia('print').matches is false The page is currently using screen media or the emulation was cleared. Select print, await the call, then evaluate the query again.
Passing null does not preserve a print state null disables CSS media emulation; it is not a request to keep print styles. Pass 'print' whenever print styling is required.
Mobile layout did not change after selecting screen Media type and device emulation are different controls. Set the device viewport and user agent separately, preferably before navigation.
PDF colors look faded or backgrounds are absent PDF printing adjusts colors by default, and the page’s print CSS may omit backgrounds. Review print CSS and consider -webkit-print-color-adjust when exact colors are needed.
The method is unavailable or the call fails The installed Puppeteer version may differ from the documentation being consulted, or the receiver is not a Page. Check the API reference for the installed version and confirm the call is made on the page object.

7. Performance, reliability, and cost

Media emulation itself is a page setting; most capture time is typically spent navigating, waiting for the site, rendering content, and writing a PDF. Choose a navigation wait condition that fits the site rather than waiting indefinitely for every network request: pages with analytics or polling may never become fully idle. If output must be repeatable, keep viewport, device settings, media type, and navigation timing consistent, and verify the active type before capture.

Puppeteer runs a browser that you manage, so account for browser installation, process lifecycle, memory, and the cost of the compute environment in your own application. This approach gives you control over the browser workflow; you are also responsible for handling failed navigations and cleaning up browser processes.

8. Or skip the browser setup

If you only need a screenshot or PDF and do not need to control Puppeteer directly, ScreenshotNeo provides a website screenshot API and MCP server. Its one-call API can return an image or PDF; see the ScreenshotNeo API documentation.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://example.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', image));

Cookie banners, newsletter popups, and chat widgets are removed before capture; each cleanup step can be turned off. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing state. AI agents can capture through the MCP server’s take_screenshot, get_page_info, and capture_pdf tools. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

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

9. FAQ

Does emulating print send a job to a printer?

No. It selects print CSS in the browser page. Use the browser’s PDF method for a PDF file.

Can I generate a screen-styled PDF?

Yes. Await page.emulateMediaType('screen') before calling page.pdf().

How do I restore normal media behavior?

Pass null to disable CSS media emulation.

Does media type emulation enable dark mode?

No. Use media feature emulation for conditions such as prefers-color-scheme; media type chooses screen or print rules.