10 Common Website Image Handling Mistakes and How to Fix Them
Fix image accessibility, layout stability, responsive delivery, and loading problems with practical markup and checks you can verify.
Website image problems usually come from a mismatch between an image’s purpose, its markup, and how it is delivered. Review the rendered page and the source: give meaningful images useful alternatives, leave decorative images silent, reserve image space, serve candidates suited to the display size, and avoid delaying the image that drives the first viewport.
This guide covers ten common mistakes and practical fixes. A site may have none, some, or several; check actual markup and browser behavior before changing it.
1. Meaningful images have missing or unhelpful alt text
For an informative image, write alternative text that communicates the relevant information to the page’s audience. Describe what the reader needs to learn or do; do not inventory every visible detail or repeat nearby text. For an icon that acts as a control, describe its function.
<!-- Informative image: describe the useful takeaway in context -->
<img src="monthly-signups.png" alt="Sign-ups rose from January to March, then leveled off in April.">
<!-- Functional icon: describe the action, not the shape -->
<button type="submit">
<img src="search.svg" alt="">
Search
</button>
The second example’s visible button text already names the action, so the icon is redundant. If an image alone provides a link or button’s accessible name, its alternative should explain the destination or function. W3C’s Images Tutorial covers informative, decorative, and functional images.
2. Decorative images have noisy alt text
If an image adds no information and is only visual decoration, use an empty alt value, alt="". This tells assistive technology it can skip the image. Do not omit the attribute: missing alt text can result in assistive technology announcing a filename or other unhelpful content.
<img src="blue-divider-flourish.png" alt="">
Decide from the image’s role in this particular page, not from its file type. A photograph may be decorative in one layout and informative in another.
3. Alt text is vague, stuffed with keywords, or too literal
Write the alternative for the image’s purpose and surrounding context. “Chart” does not explain a chart’s takeaway. A long list of colors, objects, and search terms is not automatically more useful. For a linked image, communicate where the link goes or what it does.
<!-- Weak: names the image but not what the reader needs to know -->
<img src="sales-chart.png" alt="Sales chart">
<!-- Better when this is the chart's key takeaway -->
<img src="sales-chart.png" alt="Online sales doubled between Q1 and Q2.">
For a complex chart, one short alt value may not carry all the information. Introduce the chart in nearby text and provide a complete data or text equivalent where readers can find it.
4. Images do not reserve their space before loading
Without dimensions or another sizing strategy, the browser may not know how much space an image needs until it arrives. Content below it can jump. Include the image’s intrinsic width and height; responsive CSS can still scale it to fit.
<img
src="team-photo.jpg"
alt="The support team at the annual planning meeting"
width="1600"
height="900"
class="content-image"
>
.content-image {
display: block;
max-width: 100%;
height: auto;
}
Use the actual intrinsic dimensions, or preserve the correct aspect ratio with an equivalent sizing strategy. Do not put the rendered CSS width in the HTML dimensions unless it happens to equal the source’s intrinsic dimensions: the attributes establish the ratio, while CSS controls the displayed size. See web.dev’s guidance on optimizing layout shift.
5. Every device downloads the same oversized image
A large source sent to a small display wastes transfer and decode work. Create image candidates suited to your layout and let the browser choose with srcset and sizes. The sizes value describes the expected rendered slot width; it does not set the image’s CSS width. Three to five candidates are common in web.dev guidance, but the right set depends on your design and operational trade-offs.
<img
src="article-800.jpg"
srcset="article-400.jpg 400w,
article-800.jpg 800w,
article-1200.jpg 1200w"
sizes="(max-width: 600px) 100vw,
(max-width: 1000px) 80vw,
800px"
width="1200"
height="800"
alt="A field researcher recording observations"
>
The browser uses the candidates, slot estimate, and device characteristics to select a source. CSS still determines the actual layout:
img {
max-width: 100%;
height: auto;
}
For a different crop at different breakpoints, use <picture> with media-specific sources and a fallback <img>. Use width descriptors such as 400w only when the corresponding file is actually about that width. Otherwise the browser’s selection assumptions are wrong. Read web.dev’s responsive image guide for candidate and service trade-offs.
6. One image format or compression setting is used for everything
There is no universally best format or quality setting for every image. Photographs, flat illustrations, transparency, browser support, and delivery requirements all affect the choice. Compare visual fidelity and file size for the actual asset, then serve appropriate alternatives where your delivery setup supports them.
<picture>
<source type="image/webp" srcset="portrait.webp">
<img src="portrait.jpg" width="1200" height="900"
alt="A ceramic bowl filled with peaches">
</picture>
For a small site, manually exporting a few variants may be enough. A build pipeline can automate resizing with tools such as Sharp or ImageMagick. An image service such as Thumbor or Cloudinary can generate and deliver variants on demand, with service configuration and operational trade-offs to consider. These are examples, not a tested ranking. Compare the number of variants you maintain, storage, markup complexity, delivery needs, and acceptable visual quality. Avoid relying on a fixed file-size reduction claim without measuring your own assets.
7. The image visible immediately is lazy-loaded
Native lazy loading is useful for images below the fold. Do not apply loading="lazy" to the prominent image visible immediately, especially when it is the page’s Largest Contentful Paint (LCP) image. Lazy loading can defer the request until after layout work identifies the image as being near the viewport.
<!-- The leading image is available immediately; do not lazy-load it -->
<img src="hero.webp" width="1600" height="900"
alt="A mountain trail at sunrise">
<!-- An image farther down the page can be lazy-loaded -->
<img src="related-story.webp" width="800" height="600"
loading="lazy" alt="A hiker crossing a wooden bridge">
Do not assume that fetchpriority="high" cancels a lazy-loading delay. First make the LCP image discoverable and eager; then decide whether a priority hint is useful.
8. The important hero image is not discoverable or prioritized
Where practical, put the important image in the initial HTML so the browser can find it early. For one genuinely critical image, fetchpriority="high" can hint that it should receive higher priority. Use the hint sparingly: prioritizing one request can affect competition with other resources.
<img src="hero.webp" width="1600" height="900"
fetchpriority="high"
alt="A mountain trail at sunrise">
If the LCP image is a CSS background or cannot be discovered from the initial HTML, a targeted preload may help. Keep the preload URL, format, and responsive candidate selection aligned with the image that the page will actually use.
<link rel="preload" as="image" href="/images/hero.webp"
fetchpriority="high" type="image/webp">
Do not preload every image or mark multiple carousel slides high priority. Check whether the image is already discovered early before adding a hint. See web.dev’s LCP guidance and its Fetch Priority guide.
9. Essential words or complex information exist only in an image
Use normal text for essential words when possible. Text in HTML can adapt to zoom, layout, and assistive technology more reliably than words baked into a raster image. If words must be part of an image, the text alternative must include those same words. For a complex diagram or chart, provide a complete text equivalent of the data or information it conveys.
<!-- Prefer real text beside the image -->
<figure>
<img src="campaign-banner.jpg" width="1200" height="400"
alt="">
<figcaption>Register for the workshop by 30 September.</figcaption>
</figure>
<!-- If the image's words are essential and have no visible equivalent -->
<img src="notice-with-text.png" width="1200" height="400"
alt="Workshop registration closes 30 September. Register online.">
Choose whether nearby visible text already provides the equivalent; avoid making screen-reader users hear the same message twice. W3C’s guides cover images of text and complex images.
10. Image changes are shipped without checking browser behavior
Source code alone cannot confirm which candidate a browser fetched, whether the image was found early, or whether its box shifted surrounding content. Inspect the page after the change.
- Open browser developer tools and inspect the Network panel. Filter for images and check the request URL, transfer size, timing, and whether the expected image loaded.
- Inspect the rendered image and its current source in the Elements panel. Check its display dimensions against the image’s intrinsic ratio and the intended
sizesslot. - Check request priority and discovery timing for the LCP image. Confirm it is not lazy-loaded and can be discovered early from the document or a justified preload.
- Reload at representative viewport widths and device pixel ratios. Confirm the browser selects a suitable candidate and the image remains correctly sized.
- Observe layout while images load. Confirm dimensions or CSS reserve the intended space.
- Recheck accessibility: inspect the alternative in context and test whether decorative images are skipped and functional images communicate their action.
- Use lab and field performance tools appropriate to the change. Compare like with like; no markup change guarantees a particular score improvement.
For more on finding late-discovered or delayed LCP images, use the LCP guide. A screenshot can help review a rendered state, but it cannot establish the alt text announced by assistive technology, the image’s network priority, or its layout behavior over time.
Cost, performance, and reliability trade-offs
- Responsive variants: More candidates can fit more display sizes, but they add generation, storage, and markup work. Start from actual layout slots and device needs.
- Format and quality: Choose per image type and delivery requirement. Inspect the rendered result and measure actual transfer size instead of assuming a universal winner.
- Automation: Build-time resizing with Sharp or ImageMagick keeps transformation under your deployment process. On-demand services can reduce manual variant work but add an external delivery dependency and its configuration.
- Loading priority: Eager loading the leading image helps make it available promptly; lazy loading below-the-fold images avoids requesting them immediately. Misapplied lazy loading and excess priority hints can work against the page’s needs.
- Reliability: Keep a valid fallback source where using alternate formats, confirm generated paths resolve, and check failed requests in the Network panel. Ensure the page remains understandable if an image is unavailable through useful text alternatives and nearby content.
- Cost: Measure bandwidth, storage, transformation volume, and maintenance against your hosting or image-service plan. The dossier provides no universal target or measured savings that applies to every site.
Quick review checklist
- Every informative image has a concise, contextual alternative.
- Decorative images use
alt=""; functional images communicate the action or destination. - Image boxes reserve space through dimensions or an equivalent aspect-ratio strategy.
- Responsive candidates describe their real widths, and
sizesreflects the expected slot. - Formats and quality are chosen for the content and checked visually.
- Only appropriate offscreen images are lazy-loaded; the LCP image is not.
- Priority hints and preloads are limited to assets that need them.
- Essential image text and complex information have text equivalents.
- Network requests, selected source, discovery, priority, and layout are checked after changes.
Or skip the browser setup
If you need a rendered screenshot while reviewing image changes, ScreenshotNeo provides a website screenshot API and MCP server. Its capture can accept cookie and consent banners like a visitor, then remove more than 60 known consent platforms as well as newsletter popups and chat widgets; each step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status. AI agents can use its MCP server tools to take screenshots, get page information, and capture PDFs.
One GET request returns an image or PDF. The following runnable examples save a screenshot of a test URL; replace the URL and API key with your own. See the ScreenshotNeo API documentation for options and response details.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-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"},
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'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const bytes = new Uint8Array(await res.arrayBuffer());
await (await import('node:fs/promises')).writeFile('shot.webp', bytes);
ScreenshotNeo also supports full-page and element captures, device presets and custom viewports, retina scale, custom CSS and JavaScript, click and wait actions, request blocking, custom headers and cookies, caching, signed public image links, asynchronous jobs, bulk capture, and PDF settings. The API accepts parameter names used by other screenshot APIs to make switching easier. ScreenshotNeo costs $0 for 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Learn about ScreenshotNeo.
Sign up for 1,000 free screenshots a month, with no card required.
FAQ
Should every image have alt text?
Every <img> should have an intentional alt attribute. Informative and functional images need an appropriate text alternative; purely decorative images generally use an empty value.
Does sizes set the image’s displayed width?
No. It tells the browser the expected slot width so it can choose among srcset candidates. CSS controls the rendered layout.
Can I use lazy loading on every image?
No. Lazy loading is intended for images that are not immediately needed. Do not lazy-load the LCP image.
Will fixing these issues guarantee a better performance score?
No. The effect depends on the page and its other resources. Verify discovery, selected source, priority, and layout behavior with browser tools and suitable performance measurements.


