HTML Image Tag

Introduction to the Image Tag

The img tag is one of the void elements in HTML - no closing tag, just the one tag with attributes - and it's also one of the elements you'll use on basically every page you ever build, so the few attributes it requires are worth knowing cold. The two you absolutely need are src which tells the browser where to find the image file, and alt which provides a text description for screen readers and for situations where the image fails to load - and this second one gets skipped more than it should, which is both an accessibility problem and an SEO miss since search engines read alt text to understand what an image shows.

Basic Syntax and Attributes

The img tag is fairly compact compared to most HTML elements - a handful of attributes does most of what you need, and the browser handles displaying the actual image. The width and height attributes are worth including even if you plan to size the image with CSS, because the browser uses them to reserve the correct amount of space before the image loads, which prevents the layout from jumping around as images come in - that jump is called Cumulative Layout Shift and it's one of the things Google measures as a page quality signal.

html
1<!-- Basic image syntax -->
2<img src="images/photo.jpg" alt="A description of the image">
3
4<!-- Image with dimension and loading attributes -->
5<img src="images/logo.png" alt="Company Logo" width="200" height="100" loading="lazy" class="logo-image">
6
7<!-- Responsive image with srcset -->
8<img src="images/hero-small.jpg"
9     srcset="images/hero-small.jpg 400w, images/hero-medium.jpg 800w, images/hero-large.jpg 1200w"
10     sizes="(max-width: 600px) 400px, (max-width: 1000px) 800px, 1200px"
11     alt="Responsive hero image">

Key Image Attributes

  • src - The path to the image file. Required. Can be a relative path, root-relative path, or full URL to an external image.
  • alt - Alternative text describing the image for screen readers, search engines, and when the image fails to load. Required for accessibility. Use empty alt="" for decorative images.
  • width and height - The intrinsic dimensions of the image in pixels. Setting these lets the browser reserve space before the image loads and prevents layout shift.
  • loading - Set to lazy to defer loading until the image is near the viewport. Use eager (the default) for images above the fold that should load immediately.
  • srcset - A list of image files with their widths, letting the browser pick the most appropriate size for the current screen.

Image Paths: Absolute vs Relative

Image paths are where beginners get tripped up most often - the browser looks for the image file relative to the HTML document unless you give it an absolute URL, and if the path doesn't match the actual file location exactly including capitalization, you get a broken image icon. I've typed the path too fast and used the wrong folder name more times than I want to admit and then spent ten minutes staring at a broken image wondering what was wrong.

html
1<!-- Full external URL -->
2<img src="https://example.com/images/picture.jpg" alt="External image">
3
4<!-- Root-relative: starts from site root -->
5<img src="/images/logo.png" alt="Site logo">
6
7<!-- Same folder as the HTML file -->
8<img src="photo.jpg" alt="Local photo">
9
10<!-- Image in a subfolder -->
11<img src="assets/images/background.jpg" alt="Background image">
12
13<!-- Go up one directory then into images -->
14<img src="../images/icon.png" alt="Icon from parent folder">

Path Types Explained

  • Absolute URLs - The full address including https:// and the domain name. Use these for images hosted on external servers or CDNs.
  • Root-relative paths - Start with a forward slash and are resolved from the site's root directory. Useful for shared assets since the path stays correct regardless of where the HTML file lives.
  • Document-relative paths - Resolved relative to the HTML file's location. Use ./ for the current directory, ../ to go up one level. Most common for small projects.

Responsive Images

Sending a 2000px wide image to a phone with a 400px screen is wasteful - the user downloads four times more data than they need and the image gets scaled down anyway. The srcset attribute solves this by giving the browser a list of image files at different sizes and letting it pick the right one based on the screen width and pixel density. The sizes attribute tells the browser how wide the image will actually be displayed at different viewport sizes, which helps it make a smarter choice. The picture element goes a step further and lets you serve completely different image crops for different screen sizes - the wide landscape version on desktop, a tighter portrait crop on mobile - which is called art direction.

html
1<!-- Responsive images with srcset and sizes -->
2<img src="images/fallback.jpg"
3     srcset="images/small.jpg 400w,
4             images/medium.jpg 800w,
5             images/large.jpg 1200w,
6             images/xlarge.jpg 2000w"
7     sizes="(max-width: 600px) 400px,
8            (max-width: 1000px) 800px,
9            (max-width: 1400px) 1200px,
10            2000px"
11     alt="Responsive image example"
12     loading="lazy">
13
14<!-- picture element for art direction or format fallbacks -->
15<picture>
16  <source media="(min-width: 1000px)" srcset="images/wide.jpg">
17  <source media="(min-width: 600px)" srcset="images/medium.jpg">
18  <img src="images/narrow.jpg" alt="Art directed image">
19</picture>

Best Practices for Using Images

Most image problems on the web come down to a few recurring habits: forgetting alt text, not specifying dimensions and causing layout shift, serving enormous files when smaller ones would do, and using the wrong format for the content type. WebP is the format worth defaulting to for most images now - it's smaller than JPEG at equivalent quality and supports transparency like PNG - though you'll want a JPEG or PNG fallback via the picture element for browser support, though WebP support is now very broad.

  • Always write descriptive alt text - a sentence describing what the image shows and why it's there, not just the filename
  • Set width and height attributes matching the image's actual dimensions to prevent layout shift during loading
  • Compress images before uploading - uncompressed photos from a camera can be 5-10MB, which is unnecessary for web use
  • Use WebP format where possible for better compression, with JPEG or PNG fallbacks via the picture element
  • Add loading="lazy" to images below the fold so they don't block initial page load
  • Use srcset and sizes for images that appear at different sizes on different screen widths
  • Match format to content: JPEG for photographs, PNG for graphics needing transparency, SVG for logos and icons

Accessibility Considerations

Alt text is the part of image accessibility that gets the most attention, and it should - bad alt text or missing alt text makes images useless or actively confusing for screen reader users. But writing good alt text is less obvious than it sounds: it should describe what the image shows in the context of the surrounding content, not just name objects in the image. A photo of a dog next to a dog food review article needs different alt text than the same photo used as a decorative header image - in the first case you'd describe the dog and maybe the breed, in the second case you'd use an empty alt attribute because the image adds no information.

html
1<!-- Descriptive alt text -->
2<img src="chart.jpg" alt="Bar chart showing 40% sales growth from 2021 to 2023">
3
4<img src="profile.jpg" alt="Portrait of Maria Rodriguez, senior developer">
5
6<!-- Decorative image: empty alt, role presentation -->
7<img src="divider.png" alt="" role="presentation">
8
9<!-- Complex image with extended description -->
10<img src="infographic.jpg" alt="Climate change summary infographic" aria-describedby="climate-desc">
11<p id="climate-desc" class="visually-hidden">
12  Detailed description of the infographic data points...
13</p>

Accessibility Guidelines

  • Informative images - Describe what the image shows and why it's relevant to the surrounding content. Aim for one concise sentence. Screen readers announce 'image' before reading the alt text so you don't need to start with 'Image of'.
  • Decorative images - Use alt="" (empty, not missing) and role="presentation" for images that are purely decorative and add no information. Screen readers skip these entirely.
  • Complex images - Charts, graphs, and infographics that contain a lot of data need a longer description than fits in alt text. Use aria-describedby to link to a full description elsewhere on the page.
  • Functional images - If the image is inside a link or button, the alt text should describe the destination or action, not the image. 'Link to contact page' not 'Envelope icon'.

Frequently Asked Questions

What happens if I don't include an alt attribute?

Missing alt text is technically invalid HTML and has real consequences. Screen readers typically read the image filename instead, which is usually something like DSC_0847.jpg or hero-image-final-v3.png - meaningless to a user who can't see the image. Search engines also use alt text to understand image content for indexing and image search. It takes seconds to write and the payoff is meaningful.

Should I use width and height attributes or CSS for image sizing?

Both, for different reasons. The width and height HTML attributes should match the image's intrinsic pixel dimensions - browsers use these to calculate the aspect ratio and reserve space before the image loads, which prevents layout shift. CSS then controls the display size and responsive behavior, like max-width: 100% to make images scale within their container. The HTML attributes and CSS work together, not as alternatives to each other.

What is the difference between JPEG, PNG, and WebP?

JPEG compresses well for photographs but doesn't support transparency and degrades with each re-save. PNG supports transparency and is lossless so it preserves sharp edges for graphics and logos, but files are larger than JPEG for photographs. WebP does both - it compresses photos better than JPEG and supports transparency better than PNG - and browser support is now very broad. The main reason to still use JPEG and PNG is fallback compatibility or tooling that doesn't support WebP export yet.

When should I use the picture element instead of img with srcset?

Use srcset on an img element when you have the same image at different resolutions and want the browser to choose the best one - the browser makes the decision automatically based on screen size and pixel density. Use picture when you need art direction, meaning different crops or compositions for different screen sizes, or when you want to offer a modern format like WebP with a fallback for browsers that don't support it.

How does loading lazy work and when should I use it?

With loading="lazy" the browser doesn't download the image until the user scrolls near it, which reduces the amount of data transferred on initial page load. Use it on any image that starts below the visible area of the page. Don't use it on images above the fold - hero images, logos, anything visible without scrolling - because lazy loading those adds a delay to content the user needs immediately. The browser handles the rest automatically, no JavaScript required.

Why is my image showing as a broken icon?

Almost always a path problem. The browser can't find the file at the location you specified in src. Check that the path exactly matches the actual file location including folder names and capitalization - file systems on Linux servers are case-sensitive, so images/Photo.jpg and images/photo.jpg are different files. Also check the file extension is correct - .jpg and .jpeg and .JPG are all different strings even if they're the same format. Open your browser developer tools and check the Network tab to see the exact URL the browser tried to load and what error it got.