ScreenshotNeo

BlogHow-to

How to Capture Website Screenshots at the Exact CSS Pixel Size

Set a precise CSS viewport, choose the right screenshot scale, and verify the saved dimensions with Playwright or Chrome DevTools.

By the ScreenshotNeo team4 October 20268 min read

To capture a website at an exact CSS pixel size, set the browser viewport to the required width and height in CSS pixels before loading the page, then export at one image pixel per CSS pixel. In Playwright, set the viewport and use scale: "css". A viewport of 1280 × 800 CSS pixels then produces a 1280 × 800 image, provided you capture the viewport rather than the full page. Check the saved file dimensions to confirm.

“Exact size” can mean the visible viewport, the entire scrollable page, or a fixed crop. Decide which one you need first: a full-page image may be much taller than the viewport. Device pixel ratio (DPR) is another separate setting: device-scale output can have more image pixels than CSS pixels.

1. Capture an exact CSS-sized viewport with Playwright

Install Playwright and its Chromium browser in a Node.js project:

npm install playwright
npx playwright install chromium

Save this as screenshot.js and run it with node screenshot.js. Replace the example URL and dimensions with your target page and requested CSS-pixel size.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  try {
    const page = await browser.newPage({
      viewport: { width: 1280, height: 800 },
    });

    await page.goto('https://example.com', { waitUntil: 'load' });
    await page.screenshot({
      path: 'page.png',
      scale: 'css',
      fullPage: false,
    });
  } finally {
    await browser.close();
  }
})();

The two key settings have different jobs:

  • viewport.width and viewport.height set the page’s visible layout area in CSS pixels.
  • scale: "css" makes the screenshot use one output pixel per CSS pixel. Playwright’s screenshot default is "device", which uses device pixels and can make output dimensions larger.

Set the viewport when creating the page, before navigation. Playwright notes that changing viewport size after a page loads can affect sites that do not expect their viewport to change. The Playwright Page API documents viewport dimensions, screenshot scale, full-page capture, clipping, and screenshot styling.

Use Python or cURL when you need to automate the capture remotely

A local Playwright script controls a browser directly. If your workflow instead calls a screenshot API, the following examples capture a URL using ScreenshotNeo. See the ScreenshotNeo API documentation for API options. Replace YOUR_API_KEY and the target URL. To request a particular CSS viewport, use the viewport parameters supported by the 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,
)
r.raise_for_status()
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}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));

For output that must have an exact width and height, verify the returned file’s dimensions. API defaults, page length, and requested capture mode can affect the resulting image. The one-pixel-per-CSS-pixel guarantee above describes Playwright’s documented scale: "css" setting.

2. Choose viewport, full-page, or crop

Capture type What it contains How to get the intended dimensions
Viewport Only the currently visible browser area. Set viewport width and height, capture with fullPage: false and scale: "css".
Full page The page’s full scrollable content. Use fullPage: true. The output height follows rendered page content, not the viewport height.
Clipped region A selected rectangle of the page. Use Playwright’s clip option with the desired page coordinates and dimensions; inspect the exported file dimensions.

For a full-page capture, a 1280 × 800 viewport does not imply a 1280 × 800 output. The page may scroll for thousands of CSS pixels. For a fixed-size deliverable, capture the viewport or a fixed rectangle, then inspect the saved image. Playwright’s screenshot API documents fullPage and clip; Chrome DevTools also distinguishes visible-viewport capture from full-size capture.

3. Capture manually with Chrome DevTools

  1. Open the page in Chrome and open DevTools.
  2. Enable Device Mode.
  3. Enter the required width and height in the responsive viewport fields.
  4. Choose whether you want the visible viewport or the full page: open the Device Mode options and select Capture screenshot or Capture a full size screenshot.
  5. Inspect the downloaded image’s dimensions with an image viewer or image metadata tool.

Device Mode exposes viewport dimensions and DPR controls. DPR describes the relationship between physical screen pixels and logical CSS pixels. Chrome’s documentation distinguishes viewport and full-size screenshots, but does not establish a screenshot output-scale control equivalent to Playwright’s explicit scale: "css". If you need exactly one output pixel per CSS pixel, verify the file produced by your Chrome and emulation setup. See Chrome DevTools’ Device Mode guide.

4. Control rendering so repeated captures are comparable

Correct dimensions do not guarantee identical page content on every run. Fonts, images, animations, lazy-loaded sections, third-party widgets, and network activity can still be changing when the image is taken. Navigation reaching the load event is not a universal signal that every page element has settled.

  • Wait for the content you need. If a key component appears after navigation, wait for its selector before capturing: await page.locator('.report').waitFor({ state: 'visible' }).
  • Use a deliberate delay only when needed. A short fixed wait can help with known delayed content, but it adds time and does not prove that a page is ready.
  • Stabilize dynamic visuals. Playwright’s screenshot style or stylePath option can inject CSS to hide or adjust dynamic elements; the documented styling also reaches Shadow DOM and inner frames. For example, a stylesheet can disable animations or hide a rotating banner.
  • Keep capture conditions constant. Use the same browser version, viewport, DPR and capture mode when comparing screenshots. This is practical repeatability guidance; it is not a guarantee that sites render identically across environments.

Be careful with lazy-loaded content in full-page captures. A full-page image includes content beyond the initial viewport, but a site may load some of that content only as it is scrolled. Confirm that the sections you need are present in the output.

5. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its one-call API returns a screenshot, so you do not have to install and manage a browser for a basic URL capture. See the API documentation for viewport and output options.

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

Cookie banners are accepted before capture, and 60+ known consent platforms, newsletter popups and chat widgets can be removed. Those cleanup steps can each be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

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

6. Verify the saved dimensions

Check the image itself rather than inferring output dimensions from the browser settings. For example, ImageMagick’s identify command prints the image dimensions:

identify page.png

For a CSS-scaled viewport screenshot, compare the reported width and height to the viewport values you set. A full-page screenshot should instead be checked against the page’s actual scrollable height; a clipped capture should be checked against the chosen rectangle. If your image viewer does not show metadata, use a command-line image tool or inspect the image dimensions in your editor.

7. Troubleshooting

Symptom Likely cause Fix
The image is twice as wide and tall as expected. Capture used device scale on a high-DPI emulated or device context. In Playwright, set scale: "css". Recheck the saved dimensions.
The screenshot has the right width but the wrong height. You captured the full page, whose height follows scrollable content, or used a different viewport height. For fixed viewport output, capture with fullPage: false; set the intended viewport height before navigation.
The page layout does not match the requested width. The viewport may have been changed after navigation or a responsive breakpoint selected different content. Create the page with the target viewport before navigation, then reload and capture.
The screenshot is the right size but has missing images or content. Lazy content, fonts, or asynchronous requests were not ready at capture time. Wait for the relevant selector or asset to appear. For full-page captures, check content that loads during scrolling.
Two captures have different visual content. Animations, rotating modules, timestamps, or third-party content changed between runs. Use Playwright screenshot styling to suppress or stabilize dynamic elements, and keep browser and capture settings consistent.
Chrome DevTools output dimensions do not match the viewport fields. DPR or emulation settings may affect output scaling; DevTools does not document a universal CSS-scale selector. Inspect the file dimensions. For explicit CSS-pixel scaling, use Playwright with scale: "css".
The screenshot is blank or navigation fails. The page may not have loaded successfully, may require authentication, or may be blocked by a bot check. Check the page in the same browser context, confirm access and navigation errors, then wait for the required content before capture.

8. Performance, reliability, and cost

For one-off manual work, DevTools avoids writing automation code. For repeated captures, Playwright makes viewport, scale and capture mode explicit, though you must install and run browser software. A remote screenshot API avoids managing a local browser process, and its cost depends on the provider’s plan and billing rules. Compare those needs before choosing a workflow.

Full-page captures can take longer than viewport captures because they include more page content and may trigger lazy loading. Waiting for network idle or an arbitrary delay can also increase capture time and may still fail to indicate that every visual element is stable. Wait for the specific content your task requires, then validate a sample output.

For ScreenshotNeo, only clean shots are billed: bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits cost nothing, and each response reports the page verdict and billing status. Plans are Free: 1,000 shots/month; Starter: $5 for 3,000; Growth: $15 for 15,000; Pro: $39 for 60,000; Scale: $99 for 250,000; Business: $249 for 1,000,000. Yearly billing gives two months free, and every feature is available on every plan. Confirm the required dimensions in the returned image when exact file size matters.

FAQ

Does a 1280-pixel CSS viewport always create a 1280-pixel image?

Only when the capture scale maps output pixels to CSS pixels. In Playwright, use scale: "css"; device-scale output can be larger. Verify the saved image.

Does setting the viewport height limit a full-page screenshot?

No. It sets the visible viewport. Full-page capture extends through the scrollable page, so its final height depends on rendered content.

Is CSS scale the same as changing an image’s resolution afterward?

No. CSS scale controls how browser CSS pixels map to screenshot output pixels. Resizing an exported image changes its raster dimensions after capture.

Can I use DevTools when the output must be exact?

Yes, but inspect the downloaded file. DevTools documents viewport sizing, DPR and capture modes; Playwright exposes the explicit scale: "css" setting.