# Dark mode website screenshots: which sites follow prefers-color-scheme, tested

> Take dark mode screenshots with Puppeteer, Playwright or one API option, and what 16 popular sites did when the browser asked for dark: 7 switched.

Published 2026-11-08 · https://shareglint.com/en/guides/dark-mode-screenshots

"Dark mode screenshot" means a picture of a website in its dark theme — for a portfolio that shows both themes, documentation screenshots that match a dark UI, or a design review. A browser does not have a dark mode for web pages as such; it passes the user's preference to the page as the CSS media feature `prefers-color-scheme`, and the page decides what to do with it. So a dark screenshot is two steps: emulate the preference, and hope the site honours it. This page shows the first step in Puppeteer, Playwright and our API, and how often the second one happened on 16 sites.

**How we tested.** On 2026-11-08 we captured 16 home pages at 1280×800 through our screenshot API twice — with and without `dark_mode` — and compared the pictures by eye and by mean brightness (0 is black, 255 white). Cookie banners were removed in both. We repeated five of the sites in Puppeteer 25.7 and one in Playwright 1.64 on the same machine.

## Puppeteer

```javascript
import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 800 });
await page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]);
await page.goto('https://react.dev/', { waitUntil: 'load' });
await page.screenshot({ path: 'react-dark.png' });
await browser.close();
```

[`emulateMediaFeatures`](https://pptr.dev/api/puppeteer.page.emulatemediafeatures) changes what `matchMedia('(prefers-color-scheme: dark)')` and CSS `@media (prefers-color-scheme: dark)` see. Set it before `goto`: on react.dev, Tailwind CSS, Vercel, docs.python.org and nodejs.org it worked just as well after the page had loaded, because those sites react to the change, but a site that reads the preference once when it starts would stay light.

## Playwright

```javascript
const context = await browser.newContext({ colorScheme: 'dark', viewport: { width: 1280, height: 800 } });
const page = await context.newPage();
await page.goto('https://react.dev/');
await page.screenshot({ path: 'react-dark.png' });
```

Playwright's [emulation docs](https://playwright.dev/docs/emulation) list the supported values: "'light', 'dark', and 'no-preference'". On react.dev, `matchMedia('(prefers-color-scheme: dark)').matches` was `true` and the body was dark grey, `rgb(35, 39, 47)`.

## Our API

```bash
curl -X POST "https://shareglint.com/v1/screenshots?wait=true" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://react.dev/", "dark_mode": true, "block_cookie_banners": true}'
```

`dark_mode` sets `prefers-color-scheme: dark` before the page loads, the same media feature as the code above. It combines with the other options (`full_page`, `device`, `scroll_video`) and is part of the cache key, so the light and the dark capture of a URL are two separate files.

## What 16 sites did

| Site | Light | Dark mode on | Result |
|---|---|---|---|
| vercel.com | 241 | 10 | switched |
| tailwindcss.com | 225 | 23 | switched |
| nodejs.org | 236 | 31 | switched |
| react.dev | 247 | 42 | switched |
| docs.python.org | 242 | 45 | switched |
| svelte.dev | 206 | 74 | switched |
| go.dev | 159 | 97 | switched (the blue hero stays blue) |
| developer.mozilla.org | 71 | 57 | home page dark in both; hardly changed |
| github.com (logged out) | 244 | 244 | no change |
| en.wikipedia.org | 233 | 233 | no change |
| stackoverflow.com | 231 | 231 | no change |
| apple.com | 82 | 82 | no change |
| python.org | 101 | 101 | no change |
| web.dev | 226 | 226 | no change |
| debian.org | 177 | 177 | no change |
| rust-lang.org | 172 | 172 | no change |

Numbers are mean brightness of the first screen. Seven of the 16 switched. The ones that did are mostly documentation and developer-tool sites whose theme follows the system by default; the ones that did not either have no dark theme on that page or keep it behind a setting. On GitHub the theme is an account setting for signed-in users; the logged-out landing page we captured did not change.

## When the dark theme is behind a switch

Wikipedia has a dark theme, but its default for visitors is "Light", chosen in its Appearance menu. Clicking the switch before the capture worked: `"click_selector": "#skin-client-pref-skin-theme-value-night"` gave a dark Main Page (brightness 37), and so did clicking "Automatic" (`#skin-client-pref-skin-theme-value-os`) together with `dark_mode`. Find the switch's selector with right-click → Inspect in Chrome; a click is cheap compared with a page that looks wrong. In Puppeteer or Playwright it is a `page.click()` after `goto`, then wait a moment for the theme to apply.

## Checking your own site's dark theme

If the site is yours, the same two captures make a cheap check before a release: the light and dark first screen of each important page, compared side by side or in a visual regression job. Things a dark capture catches that a glance at the CSS does not: a logo with a dark transparent background that disappears, a hard-coded white card, an embedded chart or map that stays light, text on images whose contrast was tuned for the light theme. Run it with `full_page` to see every section, and with a phone `device` preset if your mobile layout has its own colours ([visual regression screenshots](https://shareglint.com/en/guides/visual-regression-screenshots)).

## No fake dark mode

What we do not do is invert a page that has no dark theme. A CSS `filter: invert(1) hue-rotate(180deg)` or Chrome's experimental auto-darkening turns black text white, but also photos negative and brand colours wrong. For a screenshot that claims to show "the site in dark mode", that picture would not be honest.

## Sizes and cost

Dark captures were not reliably smaller in our test (JPEG sizes moved by −7 % to +12 %). A dark-mode capture costs the same as a light one: 1 render of the quota for the first screen, 2 for a full page, and repeats within 24 hours are free ([pricing](https://shareglint.com/en/pricing)). For both themes side by side, capture twice and put each picture in the `browser-frame` template (its `screenshot` field takes the image URL), or shrink them for a grid as in [website thumbnails](https://shareglint.com/en/guides/website-thumbnails). The CSS side of the media feature is documented on [MDN: prefers-color-scheme](https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-color-scheme) — useful if your own site is the one that should switch.

## FAQ

### How do I take a dark mode screenshot of a website?

Tell the browser that the user prefers a dark colour scheme before the page renders. In Puppeteer: page.emulateMediaFeatures([{ name: 'prefers-color-scheme', value: 'dark' }]). In Playwright: browser.newContext({ colorScheme: 'dark' }). With our API: "dark_mode": true. The page switches only if it has a dark theme tied to that setting.

### Why is my dark mode screenshot still light?

Because the site has no automatic dark theme. Of 16 sites we tested, 8 looked the same with dark mode on: GitHub's logged-out home, Wikipedia, Stack Overflow, Apple, python.org, web.dev, Debian and rust-lang.org. Some of them have a dark theme behind a switch; clicking that switch before the capture works, as it did on Wikipedia.

### Can a screenshot tool force any site into dark mode?

Not faithfully. Chrome has an experimental auto-darkening feature and you can invert colours with a CSS filter, but both recolour a design that was never made dark, photos and logos included. Our API only asks for the site's own dark theme; it does not invert pages.
