Ch. 5 · HTML & CSS

HTML Alt Text Based on Image Purpose

Writing alt text by asking what the image does on the page: informative, functional, decorative or complex, with real before-and-after examples.

~6 min readbeginnerupdated Oct 7, 2026

The alt attribute is the text that stands in for an image when the image isn’t seen: read aloud by a screen reader, shown when the image fails to load, indexed by search engines, and used by some browsers’ reader modes. The common advice “describe the image” is where most bad alt text comes from. Good alt text doesn’t describe the picture; it does the job the picture does on that page.

So the first question is never “what’s in this image?” It’s “why is this image here?” The W3C’s alt decision tree is organised around that question, and the answers fall into a handful of categories.

Informative images: say what the reader needs

An informative image conveys content the text doesn’t. Take a photo of a conference speaker in an event recap:

<!-- describes pixels, misses the point -->
<img src="/img/talk.jpg" alt="Image of a woman standing on a stage with a microphone">

<!-- conveys what the photo is doing in the article -->
<img src="/img/talk.jpg" alt="Priya Raman presenting the opening keynote to a full hall">
HTML

The first version wastes words. Screen readers already announce “image” (or “graphic”), so “Image of” is read twice. It describes visual details nobody asked about. The second says who and what, and “full hall” carries the one detail the article’s author probably included the photo to show.

The same photo in a speaker directory, next to a heading with her name, needs different alt text, or none. If the name is already right there, alt="Priya Raman" repeats it; alt="" may be the better choice, or something that adds information, like “Priya Raman, smiling, in front of a whiteboard” for a profile where appearance is the point. Context decides.

Length: there’s no hard limit, but screen readers can’t pause inside alt text the way they can inside a paragraph, and some truncate around 125 to 150 characters. If you need more than a sentence or two, the content belongs in the page.

Functional images: describe the action

When an image is the only content of a link or a button, its alt text becomes the link or button’s name. It must say what happens, not what the icon looks like:

<a href="/">
  <img src="/logo.svg" alt="Stacktrick home">
</a>

<button type="button">
  <img src="/icons/printer.svg" alt="Print this page">
</button>
HTML

alt="Logo" would give a screen reader user a link called “Logo”. alt="Printer icon" would give them a button called “Printer icon”, which describes a shape rather than an action. Users who browse by a list of links (a common screen reader feature) see only these names, so they have to make sense on their own.

If a link contains both an image and visible text that says the same thing, the image should have alt="" so the name isn’t doubled (“Trail Runner 3 Trail Runner 3”).

Decorative images: empty alt, not missing alt

Some images add nothing to the meaning: a background flourish, a divider, a stock photo beside a paragraph that already says everything. These get an empty alt:

<img src="/img/wave-divider.svg" alt="">
HTML

alt="" tells assistive technology to skip the image entirely. Leaving the attribute out is different and worse: with no alt, many screen readers fall back to reading the file name, so the user hears “wave-divider dot svg” or, on a CMS, something like “IMG underscore 4032 dot jpeg”. Automated checkers flag missing alt for this reason; they can’t flag a wrong one.

Better still, if an image is purely decorative, consider moving it to CSS (background-image), which keeps it out of the content altogether.

Be careful with the “decorative” label. A photo in a news article often feels decorative to a developer but is part of the reporting. When in doubt, ask whether a reader who couldn’t see it would miss information.

Images of text

A banner that says “Spring sale: 30% off running shoes” as pixels needs exactly that text as its alt. Better: render it as real text over a background, so it scales, translates, and stays readable at high zoom. WCAG’s 1.4.5 (Images of Text) asks you to use real text wherever the presentation can be achieved with CSS. Logos are the accepted exception.

Complex images: short alt plus a real explanation

A chart or a diagram can’t be reduced to a sentence. Give it a short alt that identifies it and the key point, then put the full data or explanation in the page:

<figure>
  <img
    src="/charts/signups-2026.png"
    alt="Line chart of monthly sign-ups in 2026, rising from 1,200 in January to 4,800 in September."
  >
  <figcaption>
    Monthly sign-ups, January to September 2026.
    <a href="#signups-table">View the data as a table</a>.
  </figcaption>
</figure>
HTML

The alt gives the trend in one sentence; the linked table gives the numbers for anyone who wants them, including sighted users who’d like to copy them. <figcaption> is visible to everyone and is associated with the figure. It is not a replacement for alt: the image still needs its own text alternative.

SVG and icon fonts

Inline SVG has no alt attribute. For an informative inline SVG, give the <svg> role="img" and a name via aria-label or a <title> child referenced by aria-labelledby. For a decorative or redundant one, such as an icon next to visible text, add aria-hidden="true" so it’s skipped:

<button type="button">
  <svg aria-hidden="true" focusable="false" viewBox="0 0 24 24"><!-- … --></svg>
  Download report
</button>
HTML

The button’s name comes from “Download report” and the icon is ignored. An SVG loaded through <img src="icon.svg"> takes normal alt text like any image. Icon fonts render glyphs from the private use area as text; screen readers may read them as nonsense characters, so they also need aria-hidden="true" and a text label elsewhere.

Writing habits that help

  • Don’t start with “image of”, “picture of” or “graphic of”.
  • End with a full stop if the alt is a sentence, so screen readers pause naturally before the next content.
  • Don’t stuff keywords. Alt text written for search engines reads badly and doesn’t improve rankings meaningfully.
  • In a CMS, make alt a required field with guidance, but allow an explicit “decorative” checkbox that outputs alt="", or editors will type “image” to get past validation.

Interview practice

A product page has four images: the product photo in the main gallery, a shopping-cart icon inside the “Add to cart” button (which also has the visible text “Add to cart”), a size chart image showing measurements for sizes S to XL, and a faint leaf pattern behind the price. Write the text alternative for each, and explain your choice.

Answer

The product photo is informative: alt="Trail Runner 3 in blue, side view" (name, colour and angle, since a gallery often has several views and the alt should distinguish them). The cart icon is redundant with the button’s visible text, so it’s decorative in context: alt="" if it’s an <img>, or aria-hidden="true" if it’s an inline SVG; otherwise the button would be announced as “cart Add to cart”. The size chart is a complex image. Its information should exist as an HTML table with sizes and measurements, either instead of the image or linked from a short alt such as “Size chart for S to XL; full measurements in the table below”. The leaf pattern is decorative: alt="", or better, a CSS background so it isn’t in the markup at all. The interview point is that each decision comes from the image’s purpose, not its content.

Keep going

More in HTML & CSS

read ✓HTML & CSS · hard

HTML Data Tables and Header Relationships

How th, scope, caption and headers/id tell a screen reader which headers describe a cell, with a two-level pricing table worked through.

~7 min readread →
read ✓HTML & CSS · easy

HTML Buttons Versus Links for Actions

Links go somewhere and buttons do something. What each element gives you for free, and what breaks when a div or an a tag fakes the other.

~6 min readread →
read ✓HTML & CSS · mid

CSS Focus Visibility and Keyboard Navigation

Why outline: none strands keyboard users, how :focus-visible decides when to show a ring, and focus styles that hold up on any background.

~6 min readread →
esc