Images, Figures, and Multimedia

Images, Figures, and Multimedia

Images, video, and audio make pages engaging and informative. HTML5 introduced native elements for all of these, along with powerful tools for responsive images, accessibility, and performance optimisation.


1. The <img> Element

The <img> element embeds an image into an HTML page. It is a void element — it has no closing tag.

<img
  src="images/mountain.jpg"
  alt="Snow-covered mountain at sunrise"
  width="800"
  height="500"
  loading="lazy"
>

All Important <img> Attributes

AttributePurposeExample value
srcURL or path to the image file"images/photo.jpg"
altText description (required)"A red barn in a field"
widthDisplay width in CSS pixels"800"
heightDisplay height in CSS pixels"500"
loadingWhen to load the image"lazy" or "eager"
srcsetList of image sources and widths"img-400.jpg 400w, img-800.jpg 800w"
sizesHint for how wide the image will display"(max-width: 600px) 100vw, 50vw"
decodingHow the browser decodes the image"async"
fetchpriorityPriority for loading"high" or "low"
crossoriginCORS setting for external images"anonymous"

2. The alt Attribute – Accessibility First

The alt attribute is one of the most important things you can write in HTML. It serves multiple purposes:

  • Screen readers read it aloud to visually impaired users
  • Browsers display it when the image fails to load or the path is wrong
  • Search engines use it to understand image content (SEO)
  • Slow connections let users decide whether to wait for the image

Writing Good Alt Text

<!-- ❌ Bad — no information -->
<img src="dog.jpg" alt="image">

<!-- ❌ Bad — keyword stuffing -->
<img src="dog.jpg" alt="dog puppy canine pet animal photo picture">

<!-- ✅ Good — descriptive and specific -->
<img src="dog.jpg" alt="A golden retriever puppy playing with a ball in the garden">

<!-- ✅ Good — describes the information the image conveys -->
<img src="bar-chart.png" alt="Bar chart showing sales grew 40% between January and March">

Decorative Images

If an image is purely decorative and adds no information, use an empty alt so screen readers skip it entirely:

<!-- Decorative divider — screen readers will ignore this -->
<img src="wave-divider.svg" alt="">

Never omit the alt attribute entirely. Missing alt makes screen readers read the full filename, which is confusing.


3. Lazy Loading

loading="lazy" tells the browser to defer loading the image until it is near the viewport. This speeds up initial page load significantly.

<!-- Load immediately (for images above the fold) -->
<img src="hero.jpg" alt="Hero banner" loading="eager">

<!-- Defer loading until near viewport (for images further down the page) -->
<img src="product-photo.jpg" alt="Product photo" loading="lazy">
  • Use loading="eager" (or omit loading) for the largest visible image on first load — especially the hero image
  • Use loading="lazy" for all images that are below the fold

fetchpriority for the Hero Image

The browser's resource scheduler may not know which image is most important. You can give it a hint:

<!-- Highest loading priority — ideal for the main hero image -->
<img
  src="hero.jpg"
  alt="Students collaborating on code"
  loading="eager"
  fetchpriority="high"
>

4. Specifying Dimensions to Prevent Layout Shift

Always provide width and height on images. The browser reserves space before the image loads, preventing Cumulative Layout Shift (CLS) — a Core Web Vitals metric.

<!-- ✅ Browser reserves 1200×630 px before image loads -->
<img src="banner.jpg" alt="Nandhoo banner" width="1200" height="630">

<!-- ❌ No dimensions — page jumps when the image loads -->
<img src="banner.jpg" alt="Nandhoo banner">

The width and height attributes set the aspect ratio used for layout. CSS can then override the actual display size:

img {
  width: 100%;
  height: auto; /* maintains aspect ratio */
}

5. Responsive Images with srcset and sizes

Different screen sizes need different image resolutions. The srcset and sizes attributes let the browser choose the best one automatically.

srcset — Provide Multiple Sizes

<img
  src="mountain-800.jpg"
  srcset="
    mountain-400.jpg   400w,
    mountain-800.jpg   800w,
    mountain-1200.jpg 1200w,
    mountain-2400.jpg 2400w
  "
  alt="Mountain landscape"
>

Each entry is <file> <width>w. The w means pixel width of that file.

sizes — Tell the Browser How the Image Will Display

<img
  src="mountain-800.jpg"
  srcset="
    mountain-400.jpg   400w,
    mountain-800.jpg   800w,
    mountain-1200.jpg 1200w
  "
  sizes="
    (max-width: 480px) 100vw,
    (max-width: 960px) 50vw,
    800px
  "
  alt="Mountain landscape"
>

How the browser uses sizes:

  1. Checks which media condition matches the current viewport
  2. Determines the display size (e.g. 50vw of a 900px viewport = 450px)
  3. Picks the smallest srcset entry that is wide enough
  4. Downloads only that one image

This means a mobile user on a 375px screen downloads a small file instead of a 2400px image.


6. <figure> and <figcaption>

Use <figure> to wrap any self-contained piece of media (image, video, code, chart) that is referenced from the main text. Use <figcaption> to add a caption.

<figure>
  <img src="neural-network.png" alt="Diagram of a three-layer neural network">
  <figcaption>
    Figure 1: A three-layer neural network with one input layer, one hidden layer, and one output layer.
  </figcaption>
</figure>

Why Use <figure> Instead of Just <img>?

  • Semantically groups media with its caption
  • Screen readers announce it as a figure
  • The caption is visually and semantically associated with the image
  • You can move or float the whole block as a unit with CSS

Multiple Images in One Figure

<figure>
  <img src="before.jpg" alt="Homepage design before redesign">
  <img src="after.jpg" alt="Homepage design after redesign">
  <figcaption>Before and after the Nandhoo homepage redesign.</figcaption>
</figure>

7. Image Formats — Choosing the Right One

FormatBest forTransparencyAnimationNotes
JPEG / JPGPhotos, complex colour gradientsNoNoLossy — small file, some quality loss
PNGGraphics, screenshots, logos, iconsYes (alpha)NoLossless — larger files
GIFSimple animationsYes (1-bit)YesLimited to 256 colours
SVGIcons, logos, illustrations, mapsYesYes (CSS)Vector — scales to any size with no quality loss
WebPEverything — replaces JPEG and PNGYesYes~25–35% smaller than JPEG at same quality
AVIFModern browsers — best compressionYesYesEven smaller than WebP, slower encoding

Format Decision Guide

Is it a photo?
  → Yes: Use WebP (with JPEG fallback)

Is it an icon or logo?
  → Yes: Use SVG if possible

Does it need a transparent background?
  → Yes: Use WebP or PNG

Does it need to animate?
  → Yes: Use WebP animation or CSS/JavaScript animation instead of GIF
  
Need maximum compatibility with older browsers?
  → Yes: Stick with JPEG and PNG

8. The <picture> Element — Art Direction and Format Switching

The <picture> element gives you full control: serve different crops for different screen sizes (art direction), or serve different formats depending on browser support.

Format Switching (WebP with JPEG Fallback)

<picture>
  <!-- Modern browsers load the WebP version -->
  <source srcset="photo.webp" type="image/webp">
  <!-- Older browsers fall back to JPEG -->
  <img src="photo.jpg" alt="Students working together on a coding project">
</picture>

The browser tries each <source> in order and picks the first one it supports. The <img> at the bottom is always the fallback.

Art Direction (Different Crops for Different Viewports)

<picture>
  <!-- Wide screens: full landscape panorama -->
  <source
    srcset="hero-landscape.jpg"
    media="(min-width: 900px)"
  >
  <!-- Medium screens: square crop -->
  <source
    srcset="hero-square.jpg"
    media="(min-width: 480px)"
  >
  <!-- Small screens: tight portrait crop -->
  <img src="hero-portrait.jpg" alt="Teenager learning to code">
</picture>

Combining Both: Format and Art Direction

<picture>
  <source
    srcset="hero-landscape.avif"
    type="image/avif"
    media="(min-width: 900px)"
  >
  <source
    srcset="hero-landscape.webp"
    type="image/webp"
    media="(min-width: 900px)"
  >
  <source
    srcset="hero-portrait.webp"
    type="image/webp"
  >
  <img src="hero-portrait.jpg" alt="Teenager learning to code">
</picture>

9. Inline SVG

SVGs can be embedded directly in HTML, giving full CSS and JavaScript control over every part of the graphic.

<!-- External SVG file — simple, cacheable -->
<img src="logo.svg" alt="Nandhoo logo">

<!-- Inline SVG — fully controlled with CSS/JS -->
<svg
  xmlns="http://www.w3.org/2000/svg"
  viewBox="0 0 100 100"
  width="80"
  height="80"
  role="img"
  aria-label="Simple smiley face icon"
>
  <circle cx="50" cy="50" r="45" fill="#FFD700" />
  <circle cx="35" cy="40" r="5" fill="#333" />
  <circle cx="65" cy="40" r="5" fill="#333" />
  <path d="M 30 65 Q 50 80 70 65" stroke="#333" stroke-width="3" fill="none" />
</svg>

When to Use Inline SVG

  • When you need to animate specific parts of the icon with CSS
  • When you need to change colours on hover or via JavaScript
  • When you need to make the icon fully accessible with aria-label

10. The <video> Element

HTML5's <video> element embeds video without any plugin.

<video
  src="intro.mp4"
  controls
  width="800"
  height="450"
  poster="intro-thumbnail.jpg"
>
  Your browser does not support HTML5 video.
</video>

Multiple Source Formats for Compatibility

<video
  controls
  width="800"
  height="450"
  poster="intro-thumbnail.jpg"
  preload="metadata"
>
  <source src="intro.webm" type="video/webm">
  <source src="intro.mp4"  type="video/mp4">
  <!-- Subtitles / captions track -->
  <track
    kind="subtitles"
    src="intro-en.vtt"
    srclang="en"
    label="English"
    default
  >
  <p>Your browser does not support HTML5 video.
     <a href="intro.mp4">Download the video.</a>
  </p>
</video>

<video> Attributes

AttributeWhat it does
controlsShows the browser's native play/pause/volume controls
autoplayStarts playing as soon as possible (muted is required for autoplay in most browsers)
mutedStarts with audio muted
loopRepeats indefinitely
posterImage shown before the video plays
preload"none" / "metadata" / "auto" — how much to buffer upfront
width / heightReserves layout space and sets aspect ratio
playsinlinePlays inline on iOS instead of going fullscreen

Autoplay Background Video (Accessible)

<video
  autoplay
  muted
  loop
  playsinline
  poster="hero-background.jpg"
  aria-hidden="true"
>
  <source src="hero-background.webm" type="video/webm">
  <source src="hero-background.mp4"  type="video/mp4">
</video>

aria-hidden="true" hides decorative background videos from screen readers.


11. The <audio> Element

The <audio> element embeds sound files with native browser controls.

<audio controls>
  <source src="podcast.ogg" type="audio/ogg">
  <source src="podcast.mp3" type="audio/mpeg">
  <p>Your browser does not support HTML5 audio.
     <a href="podcast.mp3">Download the episode.</a>
  </p>
</audio>

<audio> Attributes

AttributeWhat it does
controlsShows native play/pause/volume UI
autoplayBegins playing when page loads (avoid — bad for accessibility and user experience)
mutedStarts muted
loopPlays repeatedly
preload"none" / "metadata" / "auto"

Audio File Formats

FormatMIME typeBrowser support
MP3audio/mpegUniversal
OGG Vorbisaudio/oggFirefox, Chrome
WAVaudio/wavAll major browsers
AACaudio/aacSafari, Chrome, Edge
WebM audioaudio/webmChrome, Firefox

Providing both OGG and MP3 covers all modern browsers.


12. Captions and Subtitles with <track>

The <track> element adds timed text tracks to <video> or <audio>. It uses the WebVTT format (.vtt files).

<video src="tutorial.mp4" controls width="800" height="450">
  <track kind="subtitles" src="subtitles-en.vtt"  srclang="en" label="English" default>
  <track kind="subtitles" src="subtitles-fr.vtt"  srclang="fr" label="Français">
  <track kind="captions"  src="captions-en.vtt"   srclang="en" label="English (captions)">
  <track kind="descriptions" src="descriptions.vtt" srclang="en" label="Audio descriptions">
</video>

Track kind Values

KindPurpose
subtitlesTranslations of spoken dialogue
captionsSubtitles + non-speech audio cues for deaf/hard-of-hearing users
descriptionsText descriptions of visual content for blind users
chaptersNamed chapter markers
metadataData used by scripts

A Basic WebVTT File

WEBVTT

00:00:00.000 --> 00:00:03.500
Welcome to the HTML5 multimedia chapter.

00:00:03.500 --> 00:00:07.000
In this section we will cover images, video, and audio.

00:00:07.000 --> 00:00:11.000
Every video should have captions for accessibility.

13. Embedding External Media with <iframe>

<iframe> embeds another web page or service inside your page — commonly used for YouTube, Google Maps, and Spotify.

<!-- YouTube video embed -->
<iframe
  width="560"
  height="315"
  src="https://www.youtube.com/embed/dQw4w9WgXcQ"
  title="Introduction to HTML5 — video lesson"
  frameborder="0"
  allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
  allowfullscreen
  loading="lazy"
></iframe>

Making iframes Responsive

Iframes have a fixed size by default. Wrap them to make them responsive:

<div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
  <iframe
    src="https://www.youtube.com/embed/dQw4w9WgXcQ"
    title="HTML5 tutorial"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
    frameborder="0"
    allowfullscreen
    loading="lazy"
  ></iframe>
</div>

padding-bottom: 56.25% creates a 16:9 aspect ratio (9 ÷ 16 = 0.5625).

Security: sandbox and referrerpolicy

<iframe
  src="https://example-user-content.com"
  sandbox="allow-scripts allow-same-origin"
  referrerpolicy="no-referrer"
  title="User submitted content"
></iframe>
  • sandbox restricts what the iframe can do (form submission, scripts, popups, etc.)
  • referrerpolicy="no-referrer" prevents your URL from being sent to the embedded page

14. Image Maps (Clickable Areas)

An image map defines clickable hotspots on a single image.

<img
  src="world-map.jpg"
  alt="World map with clickable regions"
  usemap="#world-regions"
  width="800"
  height="400"
>

<map name="world-regions">
  <area shape="rect"   coords="50,50,200,200"  href="europe.html"   alt="Europe">
  <area shape="circle" coords="600,150,80"     href="asia.html"     alt="Asia">
  <area shape="poly"   coords="100,300,200,280,220,350,120,360" href="africa.html" alt="Africa">
  <area shape="default"                        href="world.html"    alt="Rest of world">
</map>

Image maps are not widely used today. Prefer CSS + HTML overlays for interactive image areas.


15. Performance Best Practices

Loading large unoptimised images is one of the biggest causes of slow web pages.

Use the decoding Attribute

<img src="large-photo.jpg" alt="..." decoding="async">

decoding="async" lets the browser decode the image off the main thread, preventing it from blocking page rendering.

Specify an Aspect Ratio in CSS

img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9; /* prevents layout shift even before image loads */
}

Image Optimisation Checklist

[ ] Compress photos before uploading (TinyPNG, Squoosh, ImageOptim)
[ ] Use WebP or AVIF instead of JPEG/PNG where possible
[ ] Set correct width and height attributes to prevent layout shift
[ ] Use loading="lazy" on all below-the-fold images
[ ] Use srcset and sizes to serve correctly sized images at each breakpoint
[ ] Use fetchpriority="high" on the largest image visible on first load (LCP image)
[ ] Never embed text in images — it is not accessible or searchable
[ ] Use SVG for icons and logos that need to scale

16. Accessibility Checklist for Media

Images:
  [ ] Every <img> has an alt attribute
  [ ] Decorative images have alt=""
  [ ] Alt text describes what the image conveys, not just what it contains
  [ ] Complex charts and diagrams have a longer description in the page text or aria-describedby

Video:
  [ ] All video has captions (<track kind="captions">)
  [ ] Important visual content has audio descriptions if not narrated
  [ ] Autoplay video is muted or paused
  [ ] Users can pause all moving content

Audio:
  [ ] Audio has a transcript available on the page or nearby
  [ ] Audio does not autoplay

Iframes:
  [ ] Every <iframe> has a descriptive title attribute
  [ ] Decorative or background iframes have aria-hidden="true"

17. Putting It All Together — A Full Media Section Example

<section aria-labelledby="media-heading">
  <h2 id="media-heading">Introduction to HTML5</h2>

  <!-- Hero image with responsive sources and lazy loading -->
  <picture>
    <source
      srcset="hero-large.avif 1200w, hero-medium.avif 800w"
      type="image/avif"
      sizes="(max-width: 600px) 100vw, 800px"
    >
    <source
      srcset="hero-large.webp 1200w, hero-medium.webp 800w"
      type="image/webp"
      sizes="(max-width: 600px) 100vw, 800px"
    >
    <img
      src="hero-medium.jpg"
      alt="A teenager typing code on a laptop, smiling"
      width="800"
      height="450"
      fetchpriority="high"
      loading="eager"
    >
  </picture>

  <!-- Video with captions and fallback -->
  <figure>
    <video
      controls
      width="800"
      height="450"
      poster="video-thumbnail.jpg"
      preload="metadata"
    >
      <source src="introduction.webm" type="video/webm">
      <source src="introduction.mp4"  type="video/mp4">
      <track
        kind="captions"
        src="introduction-captions.vtt"
        srclang="en"
        label="English captions"
        default
      >
      <p>
        Your browser does not support HTML5 video.
        <a href="introduction.mp4">Download the video.</a>
      </p>
    </video>
    <figcaption>
      Watch the 5-minute introduction to HTML5 on Nandhoo.
    </figcaption>
  </figure>

  <!-- Audio podcast episode -->
  <figure>
    <audio controls preload="metadata">
      <source src="podcast-ep1.ogg" type="audio/ogg">
      <source src="podcast-ep1.mp3" type="audio/mpeg">
      <p>
        Your browser does not support HTML5 audio.
        <a href="podcast-ep1.mp3">Download the episode.</a>
      </p>
    </audio>
    <figcaption>Episode 1: Getting started with web development.</figcaption>
  </figure>

  <!-- Diagram with caption -->
  <figure>
    <img
      src="html-structure.svg"
      alt="Diagram showing HTML document structure: html > head and body > various elements"
      width="600"
      height="400"
      loading="lazy"
    >
    <figcaption>Figure 1: The hierarchical structure of an HTML document.</figcaption>
  </figure>

</section>

18. Common Mistakes

MistakeWhy it mattersFix
Missing alt attributeScreen readers announce the filenameAlways include alt
Using alt="image" or alt="photo"Adds no informationDescribe the image content
Forgetting width and heightCauses layout shift (poor CLS score)Always set both
Uploading 4MB unoptimised photosSlows page load dramaticallyCompress and use WebP
No captions on videoHard of hearing users cannot followAdd <track kind="captions">
Autoplay video with soundStartles and frustrates usersUse muted with autoplay
Omitting title on <iframe>Screen reader users have no contextAdd a descriptive title
Embedding text inside imagesNot readable by search engines or screen readersUse HTML text, style with CSS
Using GIF for animationVery large files, poor qualityUse WebP animation or CSS/JS

19. Mini Exercises

  1. Create an <img> tag for a photo of a sunset. Write good alt text, set width="1200" and height="675", and add loading="lazy".
  2. Wrap the image from exercise 1 in a <figure> with a <figcaption> describing when the photo was taken.
  3. Create a <picture> element that serves a WebP version of a hero image on modern browsers, falling back to JPEG on older ones.
  4. Add srcset with three sizes (400w, 800w, 1600w) and appropriate sizes to the <img> fallback.
  5. Create a <video> element with both MP4 and WebM sources, a poster image, captions track, and native controls.
  6. Create an <audio> player with MP3 and OGG sources and a link to download the file for browsers without audio support.
  7. Embed a YouTube video using <iframe>. Add a loading="lazy" attribute and a descriptive title.

20. Review Questions

  1. What happens if you omit the alt attribute from an <img> entirely?
  2. What is the difference between alt="" and alt="decorative image"?
  3. What does loading="lazy" do and when should you NOT use it?
  4. How do srcset and sizes work together to serve the right image size?
  5. What is the difference between <picture> for art direction and <picture> for format switching?
  6. When should you use inline SVG instead of an <img src="icon.svg">?
  7. What does the poster attribute on <video> do?
  8. Why should autoplay video almost always include muted?
  9. What is the <track> element and what does kind="captions" mean?
  10. What does sandbox do on an <iframe> and why is it important?