ScreenshotNeo

BlogHow-to

How to Add an Image in HTML

Learn how to add images in HTML with correct paths, accessible alt text, responsive sources, captions, troubleshooting, and performance tips.

By the ScreenshotNeo team1 October 20267 min read

The HTML element for displaying an image is <img>. Give it a valid src path and meaningful alt text:

<img src="images/photo.jpg" alt="A red bicycle leaning against a brick wall" width="800" height="600">

src identifies the image file. alt provides a text alternative for people who cannot see the image and for cases where the file cannot load. The <img> element is a void element, so it has no closing tag. See the MDN <img> reference.

1. Create the basic image

Assume this project structure:

project/
├── index.html
└── images/
    └── photo.jpg

In index.html, reference the file relative to the HTML document:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Image example</title>
  </head>
  <body>
    <img
      src="images/photo.jpg"
      alt="A red bicycle leaning against a brick wall"
      width="800"
      height="600"
    >
  </body>
</html>

A relative URL such as images/photo.jpg is resolved from the location of index.html. You can also use an absolute URL:

<img
  src="https://example.com/images/photo.jpg"
  alt="A red bicycle leaning against a brick wall"
>

For maintainability, hosting project images with your site and using relative paths is usually simpler. Check the exact folder, filename, capitalization, and extension when a local image does not appear.

2. Write useful alt text

Describe the information the image contributes in its surrounding context. Do not describe the HTML syntax or use a filename as the alternative.

Image purpose Good markup Why
Informative photo alt="A red bicycle leaning against a brick wall" Conveys the relevant visual information.
Functional link or button alt="Download the annual report" Describes the action.
Decorative flourish alt="" Marks it as decorative for assistive technology.

Use an empty alt value for a purely decorative image. Do not omit alt casually: an omitted attribute can leave assistive technology without a clear alternative.

<!-- Informative image -->
<img src="images/map.png" alt="Map showing the trail from the visitor center to the lake">

<!-- Decorative image -->
<img src="images/divider-flourish.png" alt="">

3. Reserve space with width and height

When the intrinsic dimensions are known, include pixel-valued width and height attributes. The browser can calculate the aspect ratio before downloading the file and reserve space, which helps prevent layout shifts. CSS can still control the rendered size.

<img
  src="images/gallery-detail.jpg"
  alt="Close-up of the carved pattern on a wooden bowl"
  width="1200"
  height="800"
>

The values should match the image’s intrinsic ratio. For example, a 1200×800 image has a 3:2 ratio. Do not use arbitrary dimensions that distort the image.

4. Make images responsive

Use srcset and sizes for resolution alternatives

When you have the same composition at multiple intrinsic widths, list candidates with srcset. Width descriptors such as 400w must match the actual pixel widths of those files. Pair them with sizes so the browser knows the expected rendered slot.

<img
  src="images/landscape-800.jpg"
  srcset="images/landscape-400.jpg 400w,
          images/landscape-800.jpg 800w,
          images/landscape-1600.jpg 1600w"
  sizes="(max-width: 600px) 100vw, 800px"
  width="1600"
  height="900"
  alt="A mountain lake beneath a cloudy sky"
>

Use this pattern when the image content is the same and only resolution changes. The browser chooses an appropriate candidate for the viewport and device.

Use <picture> for art direction or formats

Use <picture> when you need a different crop for a breakpoint or want to offer alternate formats. Keep a fallback <img>; it carries the alt text.

<picture>
  <source
    srcset="images/portrait.avif"
    media="(max-width: 600px)"
    type="image/avif"
  >
  <source srcset="images/landscape.webp" type="image/webp">
  <img
    src="images/landscape.jpg"
    alt="A kayaker crossing a calm lake"
    width="1200"
    height="800"
  >
</picture>

Use srcset for same-composition resolution choices and <picture> when the crop or media format should change. The MDN <picture> documentation covers source selection details.

5. Lazy-load images below the fold

loading="lazy" allows the browser to defer an off-screen image until it is closer to the viewport:

<img
  src="images/gallery-detail.jpg"
  alt="Close-up of the carved pattern on a wooden bowl"
  width="1200"
  height="800"
  loading="lazy"
>

Do not lazy-load an image needed in the initial viewport, such as a page’s main hero image. Keep dimensions on lazy-loaded images so deferred content still has reserved space. See MDN’s loading guidance.

6. Add a visible caption with <figure>

Use <figure> and <figcaption> when the image needs visible context, attribution, or a description:

<figure>
  <img
    src="images/dinosaur.jpg"
    alt="The head and torso of a dinosaur skeleton"
    width="200"
    height="171"
  >
  <figcaption>A Tyrannosaurus skeleton on display in a museum.</figcaption>
</figure>

The caption is visible page content. Keep alt focused on a useful text replacement rather than duplicating the caption. The MDN figure and figcaption guide explains the semantic relationship.

7. Control presentation with CSS

HTML attributes describe the source and intrinsic ratio. CSS controls the displayed size and fit:

.article-image {
  display: block;
  max-width: 100%;
  height: auto;
}

.thumbnail {
  width: 240px;
  height: 160px;
  object-fit: cover;
}
<img
  class="article-image"
  src="images/landscape.jpg"
  alt="A kayaker crossing a calm lake"
  width="1200"
  height="800"
>

max-width: 100% prevents an image from overflowing a narrow container. height: auto preserves its ratio. Use object-fit: cover only when cropping inside a fixed box is intentional.

8. Why an image is not showing

Symptom Likely cause Fix
Broken-image icon Wrong relative path Resolve the path from the HTML file’s directory. For a sibling images folder, use images/photo.jpg.
Works locally, fails on deployment Filename capitalization differs Match case exactly. Many production file systems are case-sensitive.
404 in the network panel File was not copied or URL is wrong Open the requested URL directly and verify the deployed file exists.
Image is stretched Width and height ratio do not match Use the intrinsic ratio and set CSS height: auto, or choose an intentional object-fit.
No accessible description Missing or generic alt Describe the image’s meaning, or use alt="" when it is decorative.
Wrong responsive file Inaccurate srcset descriptor or sizes Make each w value equal the file’s intrinsic width and describe the rendered slot accurately.
Image loads too late Important image was lazy-loaded Remove loading="lazy" from images needed in the initial viewport.
External image blocked Hotlink protection, authentication, or Content Security Policy Host the asset yourself, configure the server policy, or use an authorized public URL.

In browser developer tools, inspect the rendered element and Network panel. Confirm the final requested URL, HTTP status, response content type, and whether the request is blocked by policy.

9. Performance and reliability checklist

  • Use the smallest intrinsic file that supports the rendered size.
  • Provide accurate width and height values.
  • Use srcset and sizes when real resolution alternatives exist.
  • Use <picture> for art direction or alternate formats.
  • Lazy-load below-the-fold images, but keep the lead image eager.
  • Write meaningful alt text for informative images and empty alt for decoration.
  • Keep image URLs stable and verify that deployment preserves their paths and capitalization.
  • Use visible captions for context or attribution instead of putting all context in alt.

10. Or skip the browser setup

If your goal is to obtain a clean image of a webpage rather than author an image element yourself, ScreenshotNeo returns a screenshot from one GET request. The API accepts PNG, JPEG, WebP, or PDF output and supports full-page capture, element selectors, responsive viewports, retina scale, custom CSS and JavaScript, waits, headers, cookies, user agents, blocking rules, caching, signed links, asynchronous jobs, bulk capture, and more. See the ScreenshotNeo API documentation.

# cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
# Python
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)
// Node.js
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(`HTTP ${res.status}`);
const fs = require('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result. An MCP server lets Claude, Cursor, and other MCP clients call take_screenshot, get_page_info, and capture_pdf. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

11. Frequently asked questions

What do I put in the src attribute?

Put the image URL or a path relative to the HTML document, such as images/photo.jpg.

Does <img> need a closing tag?

No. It is a void HTML element and must not wrap child content or use </img>.

Should every image have alt text?

Every image should have an alt attribute. Use meaningful text for informative images and alt="" for purely decorative ones.

When should I use <picture> instead of srcset?

Use srcset for different resolutions of the same composition. Use <picture> when the crop or file format should change based on media conditions.

Can CSS add an image instead?

CSS background-image is appropriate for decoration. Use semantic <img> markup when the image conveys content that needs an alternative text.