A transparent PNG is a PNG image with an alpha channel: a fourth value per pixel, from 0 (fully see-through) to 255 (fully opaque), stored next to the red, green and blue values.
In screenshots, transparency is what lets you capture a badge, a logo, a chart or a sticker and drop it on any background without a white box around it. The browser does not produce it by default. This entry is part of the screenshot and rendering glossary.
A plain explanation
A normal screenshot is a rectangle of solid colour. Even "empty" parts of a page are white, because the browser paints a white canvas behind every document. A transparent capture skips that canvas, so wherever the page itself paints nothing, the pixel is stored as see-through. Soft edges, such as anti-aliased corners and shadows, become partly transparent, which is why they blend smoothly into whatever is behind them.
Opaque and transparent, side by side
We captured a rounded badge with a drop shadow on a page with no background of its own, once normally and once with the background omitted, then placed both on a checkerboard so the alpha channel is visible:
omitBackground: false and true on 2026-10-15, composited onto a checkerboard afterwards.We then counted the alpha values in each output:
| Capture | Alpha channel | Fully transparent pixels | Partly transparent pixels | Bytes |
|---|---|---|---|---|
No page background, omitBackground: false |
no | 0% | 0 | 6,092 |
No page background, omitBackground: true |
yes | 62.8% | 8,556 | 6,522 |
body { background: #fff }, omitBackground: true |
no | 0% | 0 | 6,092 |
body { background: transparent }, omitBackground: true |
yes | 62.8% | 8,556 | 6,522 |
JPEG, omitBackground: true |
no (white) | 0% | 0 | 4,358 |
Element capture of the badge, omitBackground: true |
yes | 0% | 746 | 4,423 |
Playwright, no page background, omitBackground: true |
yes | 62.8% | 8,556 | 6,522 |
The third row is the common surprise: a page that sets a white body background stays opaque, and Chrome then writes a plain RGB PNG, byte for byte the same as the normal capture. The 8,556 partly transparent pixels are the shadow and the anti-aliased edge. The element capture shows only 746, because its box is cropped to the badge border and leaves most of the shadow outside.
How it works technically
PNG stores pixels as RGB or RGBA. The browser composites the page onto a surface; normally that surface starts white. With background omission, Chrome sets the default background colour to transparent through the DevTools Protocol before it paints, so unpainted areas keep alpha 0. Everything the page paints still counts: a background on html or body, a full-size wrapper with a colour, or an iframe with its own white document. WebP and AVIF can store alpha too; JPEG cannot, so the encoder fills transparent areas with white.
How to capture it in Puppeteer, Playwright and RenderScreenshot
Make sure the page does not paint a background, then omit the browser's.
Puppeteer:
import puppeteer from 'puppeteer'; const browser = await puppeteer.launch(); try { const page = await browser.newPage(); await page.setViewport({ width: 400, height: 120 }); await page.goto('https://example.com/badge', { waitUntil: 'load' }); await page.addStyleTag({ content: 'html, body { background: transparent !important; }' }); await page.screenshot({ path: 'badge.png', omitBackground: true }); } finally { await browser.close(); }
Playwright:
import { chromium } from 'playwright'; const browser = await chromium.launch(); try { const page = await browser.newPage({ viewport: { width: 400, height: 120 } }); await page.goto('https://example.com/badge'); await page.addStyleTag({ content: 'html, body { background: transparent !important; }' }); await page.screenshot({ path: 'badge.png', omitBackground: true }); } finally { await browser.close(); }
RenderScreenshot uses output.transparent, for PNG and WebP only. Add the same style with page.styles when the page sets a background. See the output options.
curl -X POST https://api.renderscreenshot.com/v1/screenshot \ -H "Authorization: Bearer $RS_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/badge", "viewport": { "width": 400, "height": 120 }, "output": { "format": "png", "transparent": true }, "page": { "styles": ["html, body { background: transparent !important; }"] } }' \ --output badge.png
With the CLI, the flag is --transparent: rs take https://example.com/badge --transparent -o badge.png.
The measurements and both browser scripts were tested on 2026-10-15 with Node 22.18, Puppeteer 24.43.1 (headless shell mode, Chrome 148), Playwright 1.64.1 (Chromium 156) and sharp for the alpha counts. example.com/badge is a placeholder for your own page. The RenderScreenshot request follows the API docs and was not run for this page.
Common mistakes
- Asking for JPEG. It has no alpha channel; transparent areas come back white.
- A background on
html,bodyor a wrapper. Override it with an injected style, as above. - Checking transparency in an image viewer with a white background. It looks identical either way. Composite it onto a checkerboard or read the alpha values.
- Expecting the shadow in an element capture. The element box excludes
box-shadow; add padding or capture a wrapper.
Related terms
- WebP: a smaller format that also keeps alpha.
- HTML to image: rendering templates such as badges and stickers.
- Device pixel ratio: sharper edges on transparent assets at 2x.
The transparent backgrounds guide covers logos and element captures with the API. To try output.transparent on your own page, get a free API key.