Alt text for images: how to write it, and when the right answer is nothing
Most alt text advice stops at "describe the image". That is the easy half, and it is where most bad alt text comes from: a description of what a picture looks like, announced to every screen reader user as "image of a smiling team in an office". The hard half is deciding whether the image needs text at all, and what the text has to do that the picture was doing.
This page is the decision, then the wording: one question that settles most images, four possible outcomes, a line-by-line sheet for the image types that come up on real client sites, and the places alt text quietly disappears after handover.
1. The question that settles most images
The HTML standard offers the best test there is: think about "how you would read the page containing the image to someone over the phone, without mentioning that there is an image present."
Read that again, because it decides almost everything. If you would say "the office in Lisbon, the one with the blue tiles", that is the alt text. If you would say nothing — because the picture is a divider, a background flourish, or a stock photo of a handshake next to a paragraph about service — then the correct alt text is nothing at all. WebAIM's version: "if I could not use this image, what would I put in its place?"
The reason this works is that alt text is a replacement, not a description. The HTML standard is explicit that the value "is supposed to contain replacement text that could be used by users instead of the image; it is not meant to supplement the image". Anything you would put in a caption, a title or a legend belongs somewhere else.
2. Four outcomes, not one
Every image on a page ends in one of four places. W3C's alt decision tree walks the same ground in the same order — text in the image, then function, then meaning, then decoration — and the order matters, because a logo that links home is a function question before it is a description question.
| Outcome | When it applies | What goes in alt | Example |
|---|---|---|---|
| Empty | The image adds no information and does nothing: dividers, background flourishes, decorative icons beside a visible text label | alt="" — present, and empty | <img src="divider.png" alt=""> |
| Short description | The image carries information a sighted reader takes from it, and one phrase covers it | The information, not the appearance | alt="Navy wool coat, front view" |
| Function | The image is the whole content of a link or a button | What activating it does, or where it goes | alt="Search", alt="Acme home" |
| Short description plus long description | The image carries more than a phrase: charts, diagrams, maps, a table published as a picture | A short identifying line in alt, with the detail in text on the page | alt="Bar chart of quarterly revenue, 2025. Full figures in the table below." |
WCAG 2.2's requirement is one sentence with a list of exceptions: non-text content needs "a text alternative that serves the equivalent purpose". The exception this page runs on is decoration — content that is "pure decoration, is used only for visual formatting, or is not presented to users" has to be "implemented in a way that it can be ignored by assistive technology". An empty alt is one way to do that; moving the image into CSS is the other.
The four rows are not ranked. An empty alt on a decorative divider is correct markup, not a shortcut, and a page with forty correct alt="" attributes is in better shape than one with forty "image of team" placeholders.
3. An empty alt is a decision, and it deletes things
This is the part that goes wrong quietly. An empty alt does not mean "no text supplied"; it means "this image is not content". In the HTML accessibility mapping, an img whose alt is the empty string "is mapped to the presentation role. It has no accessible name."
So alt="" is a switch with two positions, both useful and both able to be wrong:
- On a decorative divider: correct. The screen reader skips it, which is the point.
- On a photo that carries meaning — the product, the chart, the person, the screenshot of the thing the client is selling — it removes that meaning from the page entirely. A sighted user still sees it, so nobody notices, and no automated check will tell you, because the attribute is present and well-formed.
The same trap exists one layer down. Images placed with CSS cannot carry alt text at all: "It is not possible to add alternative text directly to CSS or other background images, so when background images do present content, that content must be made accessible within the page markup." Decorative art in CSS is fine, and is what the HTML standard recommends for site-wide decoration. A headline, a price or a meaningful icon in CSS is content nobody can hear.
Two habits make the empty value work. Icons beside a visible label get alt="" — where the icon is "supplemental to a text label conveying the same meaning", the attribute "must be present but must be empty", because repeating the label makes a screen reader say it twice. And never fill the gap with a filename or the word "image": when alt is missing on something functional, screen readers "will typically announce the image file name, the image URL, or the URL for the link destination".
4. One line per image type
These are the rows that come up on agency work. The right-hand column says where each rule comes from — a quoted source, or this page's reading of one.
| Image | What to write | Where it comes from |
|---|---|---|
| Logo that links home and is the only thing in the link | The destination: alt="Acme home" | W3C functional images: a linked logo carries "W3C home"; WebAIM: the company name "will usually suffice" |
| Logo inside a link that already says "Acme" | alt="" | W3C functional images: an empty value is applied "to avoid redundancy and repetition"; the standard says the same for icons beside text |
| Icon-only button (search, print, close) | The action: alt="Search", alt="Print this page" | W3C functional images: "print this page" rather than "printer" |
| Icon inside a link with visible text, e.g. a PDF marker next to "Download the application" | Only the extra information: alt="PDF" | WebAIM's PDF icon example |
| Headshot of a named person | alt="Ellen Ochoa, astronaut" — name and role, not "image of" | WebAIM's worked example, where "Image of Ellen Ochoa" is called redundant |
| Product photo in a grid | What a buyer needs that the picture shows: colour, type, view | This page's reading of W3C's informative-image rule ("a short description conveying the essential information") |
| Chart, graph, diagram, map | A short line naming what it plots, plus the figures as text on the page | W3C complex images: "a two-part text alternative is required" |
| Screenshot of an interface or an app | The screen and the state: alt="Checkout, with the card error showing" | This page's reading; treat it as complex if the detail matters |
| Image of text (poster, quote card, banner headline) | The same words as the image, and replace it with real text if it is not a logo | W3C images of text: "the text alternative should contain the same words as in the image" |
| Decorative divider, pattern, stock flourish | alt="" | WebAIM's separator example; WCAG 1.1.1's decoration exception |
| Figure with a visible caption | Still needs alt; the caption does not replace it | WebAIM: the img "still needs alt text"; the mapping falls back to a figcaption only when there is no alt and no title |
| QR code | What it is for and where it goes, in words — not the URL string | This page's reading of the functional-image rule. No QR-specific guidance appears in the W3C images tutorial or the WebAIM article, so treat this row as reasoning, not a citation |
If a row is not on this sheet, W3C's decision tree is the better authority — and it says so itself: the tree "does not cover all cases". Neither does this table.
5. There is no character limit
People ask for the number, and the honest answer is that there isn't one. WCAG 2.2's text-alternative criterion says nothing about length, and W3C's own explanation of it allows that "short and long text alternatives can be used as needed to convey the information in the non-text content." A chart that needs four sentences of numbers needs four sentences of numbers.
What does exist is house style. WebAIM's is the most quoted: alt text should be "as succinctly as possible, without sacrificing accuracy", and "typically, only a few words are necessary, though rarely a short sentence or two may be appropriate". If a tool tells you alt text must fit inside a character count, that number is the tool's rule, not the standard's.
Three tests catch text that has grown too long, all from the standard's own guidance: it repeats what the visible text beside the image already says; it reads like a caption; or it contains information that is not in the image. Any of those means the sentence belongs in the body copy, and the alt should go back to what a reader would lose if the image vanished.
6. alt is not a caption, a title, a filename or a keyword field
These get confused constantly, and the confusion is expensive because each one behaves differently in the browser.
| What you write | What it actually does | Use it when |
|---|---|---|
alt | The replacement text and the accessible name of the image | Always, on every img — empty if the image is decorative |
<figcaption> | A visible caption for everyone | The text should be seen by sighted readers too. It does not replace alt |
title | Supplemental information; on an image it is used as a name only after alt is unavailable | Rarely. It is a tooltip for a desktop mouse, not a fallback for a missing alt |
aria-label | Overrides alt as the accessible name | When the name has to be computed by script or assembled from state. On a plain img it is a second way to do the same job, and it wins — so an aria-label left over from an old component silently replaces good alt text |
A linked long description, or aria-describedby | The long description for a complex image | Charts and diagrams. Note that aria-describedby is read "as one continuous paragraph of text", so structure is lost — put the table on the page and link to it instead |
| The filename, or keywords for search | Nothing. The filename is what gets announced when alt is missing | Never |
That last row deserves one more sentence, because it is the most common commercial mistake: alt text does help a search engine understand an image, and that is a side effect of writing a real description — not a reason to stuff one in. A screen reader user hearing a comma-separated keyword list learns nothing about the picture.
7. Where alt text disappears after handover
Almost no site fails because a developer did not know the rule. Sites fail because the person who knows what the image means is not the person filling the field, and the field is optional. It goes missing in four predictable places: the component ships with alt="" or the filename and nobody revisits it because it renders fine; the CMS field is marked optional, so it is treated as optional; the client uploads twenty product photos in month two, long after the review; and the image is a background in a component that has no alt field at all.
Two things fix most of it, and neither is technical. Name the person responsible for alt text in the handover document — usually whoever writes the content, not the developer. And put the rule in one line next to the field: if the image vanished, what would the reader lose? Write that. If the answer is nothing, leave the field empty and say so.
The review pass. Read the alt text of a page in order, with the page in front of you and nothing else. Can you follow what the page is about? Every "image", every filename, every empty string on something that carries meaning shows up immediately when that is all you read. It takes about five minutes a page, and it finds more than any scanner.
The rest of the record — what was tested, what was found, and what the client can hand over — is the audit report's job, and the report guide covers that shape.
8. What no tool can tell you about your alt text
The HTML standard says the quiet part out loud. It warns against pressuring markup generators into "replacing the error of omitting the alt attribute with the even more egregious error of providing phony alternative text, because state-of-the-art automated conformance checkers cannot distinguish phony alternative text."
That sentence is about every scanner on the market, ours included. A check can see whether the attribute exists, and whether it is empty. It cannot see whether the words are any good — and the better a page gets at alt text, the less a scanner has to say about it.
So, plainly: AuditReady's image check reports an img or an image button with no alt attribute at all, never reports alt="", and does not look at aria-label — which means an image named only by aria-label is still reported even though a browser would announce it correctly.
This page also does not cover PDFs and office documents, video captions and audio description, images in email, native apps, or the alt text fields inside social platforms. Each has its own rules and its own place to put the text, and guessing from web guidance is how a document ends up with no reading order at all.
And one limit that belongs to the whole automated approach: no JavaScript runs in the page we read, so an image injected by script after load is not in the HTML we see. Where the machine pass sits in a wider test, and what to do with the findings afterwards, the accessibility audit checklist covers both, in order.
9. The short version
- Ask what a reader would lose if the image vanished. Write that. If the answer is nothing, write
alt="". - If the image is inside a link or a button, write the action or the destination, not the picture.
- If the image is a chart, the
altis one line and the numbers go on the page as text. - Never write "image of", never paste the filename, never fill the field with keywords.
- No character limit exists. Cut anything that repeats the visible text, reads like a caption, or is not in the picture.
Alt text is the cheapest accessibility fix on any site and the easiest to fake. The difference between the two is one question, asked before the field is filled in.
Written 13 November 2026.