Recommended Free Tools
Use page.emulateMediaFeatures() to test CSS preferences such as dark mode and reduced motion in Puppeteer. To switch between screen and print styles, use page.emulateMediaType() instead. These APIs change different parts of browser state, so choose the one that matches the behavior you need to test.
Emulate CSS media features
Pass an array of objects with a name and value to page.emulateMediaFeatures(). For example, this sets a dark color scheme and requests reduced motion:
As an Amazon Associate I earn from qualifying purchases.
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
{ name: 'prefers-reduced-motion', value: 'reduce' },
]);
const state = await page.evaluate(() => ({
dark: matchMedia('(prefers-color-scheme: dark)').matches,
reducedMotion: matchMedia('(prefers-reduced-motion: reduce)').matches,
}));
console.log(state);
The result should report true for each matching query. Checking matchMedia() helps confirm that the browser reports the requested preference; it does not by itself verify that the page’s styles or interactions respond correctly.
Set the emulation before loading the page when the preference may affect code or rendering during startup:
#1 Best Overall
const page = await browser.newPage();
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
]);
await page.goto('https://example.com');
The documented API accepts an optional array. The official examples cover prefers-color-scheme with dark and prefers-reduced-motion with reduce; they are examples, not a guarantee that every feature and value works identically across all browser and Puppeteer versions. See the Puppeteer API reference for emulateMediaFeatures and verify less common combinations in the version your project runs.
Switch between screen and print media
Use page.emulateMediaType() to select a CSS media type. The documented values are 'screen', 'print', and null; null disables CSS media emulation.
Rank #2
await page.emulateMediaType('print');
const printMatches = await page.evaluate(() => matchMedia('print').matches);
console.log(printMatches); // true
await page.emulateMediaType('screen');
const screenMatches = await page.evaluate(() => matchMedia('screen').matches);
console.log(screenMatches); // true
await page.emulateMediaType(null); // Disable CSS media emulation
Use this API to exercise rules such as @media print or @media screen. It is separate from setting preferences such as color scheme or reduced motion. See the Puppeteer API reference for emulateMediaType.
Choose the right emulation API
| Testing need | Puppeteer API | What it changes |
|---|---|---|
| CSS preference, such as dark mode or reduced motion | page.emulateMediaFeatures([...]) |
Named CSS media features |
| Screen or print styles | page.emulateMediaType('screen'|'print'|null) |
CSS media type |
| Device viewport and user agent | page.emulate(device) |
Device metrics and user agent |
| Vision-deficiency rendering | page.emulateVisionDeficiency(type) |
A simulated vision deficiency |
page.emulate(device) is a shortcut for setting the user agent and viewport. Puppeteer advises applying it before navigation because a site may not expect its size to change afterward. It does not replace the media-feature or media-type APIs. For a vision-deficiency simulation, use page.emulateVisionDeficiency(); documented examples include achromatopsia, deuteranopia, blurredVision, and reducedContrast, with none to reset. That simulation is distinct from changing a CSS media query. See the device emulation reference and vision deficiency API reference.
Generate a PDF with the intended styles
page.pdf() uses the print CSS media type. If the PDF should use screen styles instead, set the media type before creating it:
await page.emulateMediaType('screen');
await page.pdf({ path: 'page.pdf' });
For print styling, leave or explicitly set the print media type:
Rank #4
await page.emulateMediaType('print');
await page.pdf({ path: 'page.pdf' });
Puppeteer’s PDF documentation notes that printing modifies colors by default. If exact color output matters, review the CSS -webkit-print-color-adjust property and test the resulting PDF. See Puppeteer’s page.pdf() reference.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Troubleshoot media emulation
- The page still looks light: Confirm that the query is
(prefers-color-scheme: dark), that you used the feature nameprefers-color-schemewith valuedark, and that the page has CSS or application logic responding to it. Check the browser’s reported state withmatchMedia(). - Animations still run: Emulating
prefers-reduced-motion: reduceonly changes the preference exposed to the page. The page must implement styles or behavior that respects that preference. Verify the matching query and inspect the page’s reduced-motion rules. - Print CSS does not appear in a screenshot: A screenshot is not automatically a print rendering. Set
page.emulateMediaType('print')before capturing if you need print styles; for PDFs, Puppeteer uses print media by default. - A PDF uses the wrong layout or colors: Decide whether the output needs print or screen CSS and set the media type accordingly before
page.pdf(). Check print color adjustment if printed colors differ from the screen. - An uncommon feature or value has no effect: The API examples do not establish support for every feature/value pair across browser engines and versions. Check the Puppeteer and Chrome versions actually used, then verify the query with
matchMedia(). - The layout differs after device emulation: Set device metrics and user agent with
page.emulate(device)before navigation, and use the media APIs separately for CSS media state.
Or skip the browser setup
If your goal is to capture a page rather than run a Puppeteer test, ScreenshotNeo provides a screenshot API and MCP server. One GET request returns an image or PDF. For example, this cURL request saves a WebP screenshot:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo documentation for request options. ScreenshotNeo removes cookie/consent banners, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers indicate the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo free: 1,000 screenshots a month, no card required.
Frequently Asked Questions
Does media emulation change how the site responds to a real user’s preference?
No. It changes the browser state for the emulated page; it does not alter the visitor’s device settings.
Can I emulate several media preferences at once?
Yes. Pass multiple {name, value} objects in the array to page.emulateMediaFeatures().
Quick Recap
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.




