ScreenshotNeo

BlogGuides

Web Image Sizes: How to Choose the Right Dimensions

Choose web image dimensions from the rendered layout, pixel density, crop, and delivery method—not a universal pixel rule.

By the ScreenshotNeo team1 October 20269 min read

There is no single correct pixel size for every web image. Start with the image’s rendered CSS size, preserve the intended aspect ratio, provide suitable source candidates for different screens, and use explicit art direction only when the crop or composition changes.

For a normal responsive content image, define a sensible srcset and accurate sizes. For different mobile and desktop compositions, use picture. For social sharing, export a separate representative image; 1200 × 630 pixels is a common Open Graph starting point, not a universal platform requirement.

1. Start with the rendered CSS size

The browser displays an image in CSS pixels. Measure the largest width the image can occupy in its layout, including container padding and responsive breakpoints. Google’s guidance says the width attribute should match the CSS pixel size used for page dimensions.

Use case How to choose the width Typical delivery strategy
Article or blog image Match the content column’s maximum CSS width srcset plus sizes
Full-bleed banner Use the largest viewport width the design supports Responsive candidates; often picture for crops
Card or thumbnail Match the card slot at each breakpoint Width candidates or a fixed thumbnail variant
Logo or icon Match its displayed dimensions and intrinsic aspect ratio SVG when appropriate, otherwise raster candidates
Open Graph preview Use a dedicated social composition Separate og:image asset

Set intrinsic width and height attributes even when CSS makes the image fluid. They help the browser reserve space and reduce layout shifts.

<img
  src="photo-800.jpg"
  width="800"
  height="533"
  alt="A cyclist riding beside a lake"
  style="max-width:100%;height:auto"
>

2. Calculate candidate dimensions for responsive images

Choose a candidate near the rendered slot width, then add smaller and larger options. A 2x candidate is useful for high-density screens, while a normal-density candidate prevents unnecessarily large downloads on ordinary displays.

For a slot that is 800 CSS pixels wide, a practical starting set might be 320, 640, 800, 1200, and 1600 pixels. These are examples; derive the final values from your actual breakpoints and image pipeline.

Use srcset with width descriptors

<img
  src="photo-800.jpg"
  srcset="photo-320.jpg 320w,
          photo-640.jpg 640w,
          photo-800.jpg 800w,
          photo-1200.jpg 1200w,
          photo-1600.jpg 1600w"
  sizes="(max-width: 640px) 100vw, 800px"
  width="800"
  height="533"
  alt="A cyclist riding beside a lake"
>

sizes tells the browser how wide the image will render. Without it, the browser cannot reliably compare candidates with the real slot size and may download a file that is too large.

Use density descriptors for fixed-size images

If an image always renders at one CSS size, density descriptors can be clearer:

<img
  src="avatar-160.jpg"
  srcset="avatar-160.jpg 1x, avatar-320.jpg 2x"
  width="160"
  height="160"
  alt="Profile photograph"
>

Do not combine density descriptors and width descriptors in the same srcset. Use width descriptors when the layout width changes; use density descriptors when the CSS size is stable.

3. Match aspect ratio and decide whether you need art direction

Keep the same aspect ratio when the composition works at every width. Use CSS such as aspect-ratio and object-fit when a fixed visual slot is required.

.card-image {
  aspect-ratio: 16 / 9;
  width: 100%;
  object-fit: cover;
  display: block;
}

Use picture when the mobile and desktop versions need different crops, focal points, or aspect ratios. Keep an img fallback with src.

<picture>
  <source
    media="(max-width: 640px)"
    srcset="hero-mobile-640.jpg 640w, hero-mobile-960.jpg 960w"
    sizes="100vw"
  >
  <source
    srcset="hero-wide-1200.jpg 1200w, hero-wide-1800.jpg 1800w"
    sizes="100vw"
  >
  <img
    src="hero-wide-1200.jpg"
    width="1200"
    height="675"
    alt="People walking through a mountain valley"
  >
</picture>

The picture element is also useful for format selection. Put modern formats first and retain a broadly supported fallback.

<picture>
  <source type="image/avif" srcset="photo-800.avif 800w, photo-1200.avif 1200w" sizes="(max-width: 640px) 100vw, 800px">
  <source type="image/webp" srcset="photo-800.webp 800w, photo-1200.webp 1200w" sizes="(max-width: 640px) 100vw, 800px">
  <img src="photo-800.jpg" srcset="photo-800.jpg 800w, photo-1200.jpg 1200w" sizes="(max-width: 640px) 100vw, 800px" width="800" height="533" alt="A cyclist riding beside a lake">
</picture>

4. Choose file formats and quality together with dimensions

Pixel dimensions alone do not determine performance. Compare rendered size, encoded file weight, format support, and visual quality.

Format Good fit Watch for
JPEG Photographs and broad compatibility Loss of fine detail at aggressive compression
PNG Transparency, screenshots, and sharp flat graphics Can be much larger for photographs
WebP General-purpose modern delivery Keep a fallback where needed
AVIF Often efficient for photographs and gradients Verify your browser and processing pipeline support
SVG Logos, icons, and other vector artwork Not a replacement for photographic pixels

Google lists BMP, GIF, JPEG, PNG, WebP, SVG, and AVIF among formats supported for images referenced by img src. Use the format that preserves the image at an acceptable byte size, then measure real page loading.

5. Handle high-density screens without overserving

A device with a 2x device-pixel ratio may need roughly twice as many source pixels in each dimension for a crisp image at the same CSS size. Supply a larger candidate, but let the browser choose it. Do not force every visitor to download the 2x file.

For an 800 CSS-pixel slot, an 800-pixel candidate covers standard density and a 1600-pixel candidate covers many 2x cases. A browser can still select a smaller source when bandwidth, viewport size, or device characteristics make that appropriate.

6. Select Open Graph and social preview dimensions

Social preview images have a different job from in-page images. They should be representative, high resolution, and composed for the card layout. A common third-party baseline is 1200 × 630 pixels (about 1.91:1), but platforms vary and can crop or resize the result. Treat this as a starting export size, then preview the actual URL on the services that matter to your site.

Keep important subjects and marks away from the edges, where cards may crop them. Google recommends a relevant, representative, high-resolution og:image and advises avoiding extreme aspect ratios.

<meta property="og:image" content="https://example.com/social/article-preview.jpg">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">

Do not reuse a narrow banner or an arbitrary in-page thumbnail as your social asset unless its composition remains clear in the preview card.

7. A repeatable workflow for choosing dimensions

  1. Inspect the layout at each breakpoint and record the largest rendered CSS width.
  2. Write down the aspect ratio and identify the image’s focal point.
  3. Decide whether one crop works everywhere. If not, plan picture sources.
  4. Generate width candidates around the real slots, including a larger candidate for high-density screens.
  5. Add accurate sizes values for every width-descriptor image.
  6. Set width, height, and meaningful alt text.
  7. Encode each candidate in an efficient format and compare visual quality at the rendered size.
  8. Preview social assets on target platforms and adjust the crop if important content is cut off.
  9. Inspect the browser’s selected resource in developer tools on slow and fast connections.

8. DIY: verify rendered dimensions in a browser

You can measure an image’s CSS box and intrinsic pixels with Playwright. This catches a common mistake: exporting a large file while the layout renders it much smaller.

import { chromium } from 'playwright';

const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1280, height: 800 }, deviceScaleFactor: 1 });
await page.goto('https://example.com/article', { waitUntil: 'networkidle' });

const report = await page.locator('img.hero').evaluate((img) => ({
  renderedWidth: img.getBoundingClientRect().width,
  renderedHeight: img.getBoundingClientRect().height,
  intrinsicWidth: img.naturalWidth,
  intrinsicHeight: img.naturalHeight,
  currentSrc: img.currentSrc
}));

console.log(report);
await browser.close();

Repeat at your mobile breakpoint and with deviceScaleFactor: 2. Compare currentSrc and the rendered box. If the browser always selects the largest candidate, check sizes, cache state, and whether CSS makes the slot wider than expected.

9. Or skip the browser setup

ScreenshotNeo can capture a rendered page or element through one request, so you can inspect real layouts without maintaining a browser service. The API removes cookie banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server lets Claude, Cursor, and other MCP clients use take_screenshot, get_page_info, and capture_pdf.

See the ScreenshotNeo API documentation for all options.

cURL

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

Python

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://example.com/article"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com/article' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));

The same API supports full-page captures with lazy images loaded, CSS-selector element captures, dark mode, device presets or custom viewports, retina scale, custom CSS and JavaScript, click and wait actions, blocked requests and resource types, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, caching with a chosen TTL, signed links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, PDF output, HTML/CSS rendering, and a usage API. Parameter names used by other screenshot APIs also work to ease migration.

Plans include 1,000 screenshots per month free with no card. Paid plans start at $5 for 3,000 screenshots; yearly billing gives two months free, and every feature is available on every plan. Create a free ScreenshotNeo account.

10. Troubleshooting

Symptom Likely cause Fix
The image looks blurry on a phone No larger density candidate Add a 2x width or density candidate and confirm it can be selected.
Mobile downloads the desktop file Missing or inaccurate sizes Describe the mobile slot, such as 100vw, in sizes.
Layout shifts while loading No intrinsic dimensions Set accurate width and height attributes or an aspect-ratio box.
Subject is cropped badly One crop cannot serve every breakpoint Use picture with a mobile-specific source and focal point.
Social card is cut off Platform crop differs from your source Keep key content away from edges and preview the published URL.
Browser ignores modern format No fallback or unsupported format Keep a conventional img src fallback inside picture.
Every request downloads the largest file Candidate list or descriptors are wrong Check comma-separated descriptors, inspect currentSrc, and remove unnecessary oversized candidates.
Screenshot shows a consent dialog The capture happened before consent handling Use ScreenshotNeo’s consent and popup removal options, or automate consent before capture.

11. Performance, reliability, and cost notes

  • Choose dimensions from the rendered slot first; reducing pixels below the slot’s needs causes blur, while greatly exceeding it increases transfer cost.
  • Use responsive candidates so slow connections and small screens do not receive desktop-sized files.
  • Use lazy loading for below-the-fold images, but do not lazy-load the primary above-the-fold image by default.
  • Keep stable filenames or cache headers for unchanged derivatives so repeat visits reuse them.
  • When generating many variants, automate naming, dimensions, format conversion, and metadata so srcset stays accurate.
  • For ScreenshotNeo captures, caching with a chosen TTL can reduce repeated work. Failed loads, bot checks, blank pages, timeouts, and cache hits are not billed; inspect X-Page-Verdict and X-Billed when handling responses.

12. FAQ

What size should a website image be?

Make the largest source close to the largest CSS slot, then provide smaller and higher-density candidates. The correct number depends on the layout and crop.

Is 1200 × 630 the required social image size?

No. It is a common Open Graph baseline. Platforms vary, so verify the preview where the link will be shared.

Should I upload images at 2x size?

Provide a 2x candidate when a crisp result on high-density screens matters, but let srcset and sizes prevent smaller screens from downloading it.

When do I need picture instead of srcset?

Use srcset for the same composition at different resolutions. Use picture when format, crop, or composition must change.

Can I use one image for both the page and social sharing?

You can, but a dedicated social composition is usually clearer because link-preview cards use different aspect ratios and cropping rules.

How can I inspect the exact image a browser selected?

Read the image’s currentSrc property in developer tools or with a browser automation script, then compare it with the rendered CSS width and device pixel ratio.