Website Image Banner Design: Responsive Sizes, Crops, Accessibility, and Performance
Design responsive website banners that keep their subject, message, contrast, accessibility, and performance across every screen size.
There is no universal website banner pixel size. Choose dimensions from the banner’s job, container width, aspect ratio, focal point, mobile crop, text contrast, file weight, and loading priority. Build a wide composition, define a crop-safe area, test it at 320 CSS pixels, and serve an appropriately sized image with srcset or <picture>.
1. Define what the banner must do
Before choosing a canvas, identify the banner’s purpose:
- Brand banner: establish visual identity and direct visitors into the site.
- Campaign banner: communicate a time-sensitive offer or announcement.
- Navigation context: orient visitors at the top of a section or landing page.
- Conversion banner: explain one benefit and support one clear action.
Write the action as HTML text whenever possible. Text baked into a bitmap becomes difficult to resize, translate, search, and read with assistive technology.
2. Choose dimensions from the layout, not a fixed standard
Measure the rendered slot at your largest and smallest supported layouts. Then choose an aspect ratio that preserves the subject and leaves room for the copy. A wide desktop banner may crop heavily on a phone, so its desktop dimensions cannot guarantee a usable mobile result.
| Decision | What to check |
|---|---|
| Container width | Maximum content width, gutters, and whether the banner reaches the viewport edge. |
| Aspect ratio | Whether the focal subject survives the change from wide to narrow containers. |
| Safe area | Keep the subject, logo, and essential message away from edges that may be cropped. |
| Text placement | Leave a calm region for HTML copy and the call to action. |
| Rendered density | Provide enough pixels for high-density displays without sending oversized files. |
Use a wide source for desktop, then test a narrow crop. If the focal point or hierarchy fails, create a separate mobile source with <picture> instead of forcing one image to serve every composition.
3. Build a crop-safe composition
- Mark the focal subject and the area that must remain visible.
- Keep faces, products, logos, and essential message space near the center or in a deliberately protected side region.
- Preview the design with center cropping and with the focal point shifted left and right.
- Place the action copy in HTML over a quiet area of the image.
- Repeat the review at desktop, tablet, and narrow mobile widths.
CSS object-position can preserve a focal point for a single composition. Art direction with <picture> is more reliable when the mobile layout needs a different crop or subject scale.
4. Responsive HTML and CSS
Use <picture> when the crop changes, and srcset/sizes when the same composition only needs different resolutions. Keep a fallback src on the <img>.
<section class="site-banner" aria-labelledby="banner-title">
<picture>
<source
media="(max-width: 600px)"
srcset="/images/banner-mobile-480.avif 480w,
/images/banner-mobile-768.avif 768w"
sizes="100vw"
type="image/avif">
<source
srcset="/images/banner-desktop-1200.avif 1200w,
/images/banner-desktop-1800.avif 1800w"
sizes="(max-width: 1200px) 100vw, 1200px"
type="image/avif">
<img
src="/images/banner-desktop-1200.jpg"
srcset="/images/banner-desktop-768.jpg 768w,
/images/banner-desktop-1200.jpg 1200w,
/images/banner-desktop-1800.jpg 1800w"
sizes="(max-width: 1200px) 100vw, 1200px"
width="1800"
height="600"
alt="A cyclist riding beside a mountain lake">
</picture>
<div class="site-banner__scrim" aria-hidden="true"></div>
<div class="site-banner__content">
<h1 id="banner-title">Plan your next route</h1>
<p>Explore trails selected for your experience level.</p>
<a class="button" href="/routes">Browse routes</a>
</div>
</section>
.site-banner {
position: relative;
isolation: isolate;
overflow: hidden;
aspect-ratio: 3 / 1;
min-height: 18rem;
}
.site-banner picture,
.site-banner img {
display: block;
width: 100%;
height: 100%;
}
.site-banner img {
object-fit: cover;
object-position: 60% center;
}
.site-banner__scrim {
position: absolute;
inset: 0;
z-index: -1;
background: linear-gradient(90deg, rgb(0 0 0 / .68), rgb(0 0 0 / .08) 70%);
}
.site-banner__content {
position: absolute;
inset: 0 auto 0 0;
display: grid;
align-content: center;
max-width: 34rem;
padding: clamp(1rem, 4vw, 4rem);
color: white;
}
@media (max-width: 600px) {
.site-banner { aspect-ratio: 4 / 3; }
.site-banner img { object-position: 65% center; }
.site-banner__content { max-width: 22rem; padding: 1.25rem; }
}
The intrinsic width and height reserve space before the image arrives and reduce layout shifts. A CSS aspect-ratio is another way to reserve that space. MDN’s image guidance covers these attributes and responsive image behavior.
5. Use modern formats and the right source size
Serve AVIF or WebP where supported, with a JPEG or PNG fallback. The browser can select a smaller candidate when srcset and sizes describe the rendered slot. Keep source dimensions close to the largest slot you actually render.
Images commonly dominate page transfer: MDN reports that imagery accounts for 51% of average website bandwidth, followed by video at 25%. Compressing the banner and avoiding a desktop-sized download on mobile therefore has a direct performance effect. See MDN’s multimedia performance guidance.
- Use AVIF or WebP for photographic banners and retain a fallback for older clients.
- Export at the largest required rendered size, not an arbitrary ultra-wide size.
- Keep quality high enough for text-free photographic detail, then inspect edges and gradients for artifacts.
- Use
loading="lazy"for banners below the fold. - Do not lazy-load a visible hero banner; Chrome guidance warns that doing so can hurt Largest Contentful Paint. See Chrome’s lazy-loading guidance.
- Preload only a truly critical hero image and avoid preloading multiple responsive candidates.
6. Make overlay text readable
Test the brightest and busiest part of the image behind the copy. WCAG guidance calls for a contrast ratio of at least 4.5:1 for normal text and 3:1 for large text. A translucent scrim, gradient, solid panel, alternate crop, or repositioned copy can create a stable reading area. Check the worst crop, not only the desktop screenshot.
Keep important words as HTML. WCAG treats images of text as restricted except where presentation is essential, and HTML text scales, reflows, and works with assistive technology. See WCAG 2.2 contrast requirements.
7. Accessibility and alt text
- Use concise, purpose-focused alt text when the banner communicates information, for example
alt="A cyclist riding beside a mountain lake". - Use
alt=""when the image is purely decorative and the surrounding HTML already conveys the purpose. - Do not repeat nearby heading and button text in the alt value.
- Ensure keyboard focus remains visible on the call to action.
- Test zoom and text enlargement so the action does not disappear behind a fixed-height crop.
Google calls alt text important metadata for accessibility and image understanding. Its Image SEO guidance also explains how crawlers discover images.
8. Reflow, zoom, and mobile checks
WCAG 2.2’s reflow requirement targets a presentation that works at a width equivalent to 320 CSS pixels without loss of information or functionality, except where a two-dimensional layout is essential. Test at 320 CSS pixels and at increased browser zoom. Confirm that:
- There is no horizontal overflow.
- The heading, supporting copy, and action remain visible.
- The image does not cover controls or focus indicators.
- Long translations do not collide with the image edge.
- The mobile crop still shows the intended subject.
W3C Technique C37 recommends a maximum width and a height rule so images fit their available layout region through zoom and viewport changes. See Technique C37 and Understanding Reflow.
9. SEO and discoverability
Use a normal HTML <img> or <picture>. Google can discover an image in the src of an image element, including an <img> child inside <picture>; CSS background images are not indexed in the same way. Provide a fallback src, descriptive alt text, and meaningful page context. For important images that might otherwise be missed, submit an image sitemap and keep reused images on a consistent URL.
10. Verify banners at scale with ScreenshotNeo
Manual browser checks are useful for a few pages, but repeated viewport, device, dark-mode, and crop checks are easier through an API. ScreenshotNeo is a website screenshot API and MCP server. It can capture a full page or one CSS-selected element, use device presets or any viewport, emulate dark mode, apply retina scale, wait for a selector, delay, or network idle, run custom CSS or JavaScript, hide selectors, and return PNG, JPEG, WebP, or PDF. It can also set cookies, headers, user agent, Authorization, timezone, and geolocation; block ads, trackers, requests, or resource types; resize images; cache with a chosen TTL; create signed links; run asynchronous jobs with signed webhooks; capture up to 100 URLs per bulk call; and expose usage and OpenAPI endpoints.
For a banner review, capture the banner selector at desktop and mobile viewports, then repeat with dark mode and any consent state your page supports. The API accepts the parameter names used by other screenshot APIs, which can simplify a migration. See the ScreenshotNeo documentation.
11. Or skip the browser setup
One request returns the screenshot. Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, timeouts, failed loads, and cache hits are never billed; the response reports the result in X-Page-Verdict and X-Billed headers. An MCP server lets Claude, Cursor, and other MCP clients use take_screenshot, get_page_info, and capture_pdf.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.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://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await Bun.write('shot.webp', bytes);
The Free plan includes 1,000 screenshots each month without a card. Starter is $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan. Create a free ScreenshotNeo account.
12. Troubleshooting checklist
| Symptom | Likely cause | Fix |
|---|---|---|
| Subject disappears on mobile | Center crop removes the focal point. | Use a mobile <source>, adjust object-position, or redesign the crop-safe area. |
| Text is unreadable | Bright or detailed pixels sit behind the copy. | Add a scrim or panel, move the copy, and verify 4.5:1 or 3:1 contrast. |
| Layout jumps while loading | No intrinsic dimensions or reserved ratio. | Set width/height or aspect-ratio. |
| Mobile loads a huge file | Missing or inaccurate srcset/sizes. |
Describe the actual slot and provide smaller candidates. |
| Hero appears late | Hero was lazy-loaded or blocked by excessive script work. | Remove lazy loading from the visible hero and reduce critical work. |
| Banner is not found in image search | It is only a CSS background or lacks context. | Use <img>/<picture>, fallback src, alt text, and page context. |
| ScreenshotNeo returns a bot or blank verdict | The page challenged automation or failed to render. | Inspect X-Page-Verdict, add an appropriate wait, and fix the page’s load or access condition; failed captures are not billed. |
| ScreenshotNeo capture is incomplete | Lazy content or late network requests were still loading. | Use full-page capture with lazy images loaded, wait for a selector or network idle, or add a delay. |
13. Reliability, performance, and cost notes
- Use deterministic fonts, image dimensions, and content when comparing captures.
- Wait on a meaningful selector or network idle instead of using a long blind delay.
- Cache unchanged pages with a TTL you choose; cache hits are not billed by ScreenshotNeo.
- Use bulk capture for up to 100 URLs per call when auditing a campaign or template.
- Capture only the banner element when page context is unnecessary; use full-page capture when you need to inspect lazy-loaded sections.
- Record verdict and billed headers so failed loads and successful captures are distinguishable in pipelines.
- For public image tags, use signed links rather than exposing an API key.
14. Practical launch checklist
- Define the banner’s job and one primary action.
- Mark the focal point and crop-safe area.
- Review desktop, tablet, and 320 CSS pixel layouts.
- Use HTML for important text and verify contrast.
- Write concise alt text, or use empty alt text for decoration.
- Implement
srcset/sizesor<picture>, a fallbacksrc, and intrinsic dimensions. - Serve AVIF or WebP with a fallback and right-size each candidate.
- Lazy-load below-the-fold banners only.
- Check zoom, keyboard focus, translations, and horizontal overflow.
- Automate representative viewport and dark-mode captures before publishing.
FAQ
What is the best banner size?
The best size matches the rendered container and preserves the focal subject at the narrowest layout. There is no single universal pixel dimension.
Should banner text be part of the image?
Keep meaningful copy in HTML. Rasterize text only when the visual treatment is essential and you can provide an equivalent accessible text alternative.
When should I use a separate mobile image?
Use one when the desktop crop loses the subject, makes the action unreadable, or requires a different visual hierarchy.
Should every banner be lazy-loaded?
No. Lazy-load banners below the fold; keep a visible hero available for the initial render.
Can I test a banner without maintaining a headless browser?
Yes. ScreenshotNeo provides a single screenshot request, CSS element capture, viewport and device controls, cleanup of common consent and overlay widgets, and an MCP server for AI clients.


