# <svg> elements with an img role must have an alternative text

> Canonical HTML version: https://rocketvalidator.com/accessibility-validation/axe/4.11/svg-img-alt
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

When an `<svg>` element is given a semantic role like `img`, `graphics-document`, or `graphics-symbol`, it signals to assistive technologies that the element conveys meaningful content — just like an `<img>` tag would. However, unlike `<img>` elements that have a straightforward `alt` attribute, SVG elements require different techniques to provide their accessible name. If no text alternative is supplied, screen reader users will encounter the SVG as an unlabeled graphic, losing access to whatever information it communicates.

This issue affects people who are blind, deafblind, or who use screen readers for other reasons. It can also impact users of braille displays and other assistive technologies that rely on programmatically determined text to represent non-text content.

## Related WCAG Success Criteria

This rule maps to **WCAG Success Criterion 1.1.1: Non-text Content** (Level A), which requires that all non-text content presented to the user has a text alternative that serves the equivalent purpose. This criterion applies across WCAG 2.0, 2.1, and 2.2, and is also required by Section 508 and EN 301 549.

Because this is a Level A requirement, it represents the most fundamental level of accessibility. Failing to meet it means some users will have no way to understand the content your SVG conveys.

## How to Fix It

There are several ways to give an `<svg>` element an accessible text alternative. Use one of the following approaches:

### Use a `<title>` child element

The `<title>` element must be a **direct child** of the `<svg>` element. It provides a short text description that assistive technologies can read. If there are multiple `<title>` children, the first one must contain text — only the first `<title>` is used.

### Use the `aria-label` attribute

Add an `aria-label` attribute directly to the `<svg>` element with a concise description of the graphic's content.

### Use the `aria-labelledby` attribute

Reference one or more existing elements on the page by their `id` values using `aria-labelledby`. This is especially useful when the description text is already visible elsewhere on the page.

### Use the `title` attribute

The `title` attribute on the `<svg>` element can also provide an accessible name, though `<title>` child elements or ARIA attributes are generally preferred for better screen reader support.

## How the Rule Works

The axe rule checks that the `<svg>` element with a role of `img`, `graphics-document`, or `graphics-symbol` has a computable accessible name. Specifically, it looks for:

- A direct `<title>` child element with non-empty text content
- An `aria-label` attribute with a non-empty value
- An `aria-labelledby` attribute that references elements with text content

The check **fails** if:

- There is no `<title>` child and no ARIA labeling attribute
- The `<title>` child is empty or contains only whitespace
- The `<title>` element is a grandchild (nested inside another element within the SVG) rather than a direct child
- There are multiple `<title>` elements and the first one is empty

## Examples

### Failing — SVG with `role="img"` and no text alternative

```html
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

Screen readers will announce this as an image but cannot describe its content.

### Failing — Empty `<title>` element

```html
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <title></title>
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

### Failing — `<title>` is a grandchild, not a direct child

```html
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <g>
    <title>A blue circle</title>
    <circle cx="50" cy="50" r="40" fill="blue" />
  </g>
</svg>
```

The `<title>` must be a direct child of the `<svg>` element itself.

### Failing — First `<title>` is empty

```html
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <title></title>
  <title>A blue circle</title>
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

Only the first `<title>` child is evaluated. Since it is empty, the rule fails even though the second one has text.

### Passing — Using a `<title>` child element

```html
<svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <title>A blue circle</title>
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

### Passing — Using `aria-label`

```html
<svg role="img" aria-label="A blue circle" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

### Passing — Using `aria-labelledby`

```html
<h2 id="chart-heading">Monthly Sales Data</h2>
<svg role="img" aria-labelledby="chart-heading" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 100">
  <rect x="10" y="50" width="30" height="50" fill="green" />
  <rect x="50" y="20" width="30" height="80" fill="green" />
</svg>
```

### Passing — Decorative SVG excluded from the accessibility tree

If an SVG is purely decorative and conveys no meaning, you can hide it from assistive technologies instead of adding a text alternative:

```html
<svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
  <circle cx="50" cy="50" r="40" fill="blue" />
</svg>
```

Note that this approach removes the `role="img"` and adds `aria-hidden="true"`, so the rule no longer applies. Only use this for truly decorative graphics — if the SVG conveys any information, it needs a text alternative.
