HTML Guides for figcaption
Learn how to identify and fix common HTML validation errors flagged by the W3C Validator — so your pages are standards-compliant and render correctly across every browser. Also check our Accessibility Guides.
The HTML <figure> element represents self-contained content — such as an image, diagram, code snippet, or quotation — optionally accompanied by a caption provided by a <figcaption> element. When a <figcaption> is present, the browser and assistive technologies already understand the relationship between the figure and its caption. This built-in semantic relationship is part of the ARIA in HTML specification, which governs how native HTML elements map to accessibility roles.
The role attribute is typically used to assign or override the ARIA role of an element for assistive technologies like screen readers. However, the ARIA in HTML specification explicitly restricts certain role assignments when an element's native semantics are already well-defined by its content. A <figure> with a <figcaption> is one such case — the presence of the caption establishes a clear semantic structure that the role attribute would interfere with.
This restriction exists for several important reasons:
- Accessibility conflicts: Adding
role="figure"is redundant since the element already has that implicit role. Adding a different role (likerole="img"orrole="group") could confuse assistive technologies by contradicting the semantic meaning established by the<figcaption>. Screen readers may ignore the caption or announce the element incorrectly. - Standards compliance: The ARIA in HTML specification states that when a
<figure>has a<figcaption>descendant, noroleattribute is allowed. The W3C validator enforces this rule. - Maintainability: Relying on native HTML semantics rather than ARIA overrides keeps your markup simpler and less error-prone. The first rule of ARIA is: "If you can use a native HTML element with the semantics and behavior you require already built in, do so."
To fix this issue, remove the role attribute from the <figure> element. The <figcaption> provides all the semantic context needed.
Examples
Incorrect: role attribute on <figure> with <figcaption>
Adding role="figure" is redundant and triggers the validation error:
<figure role="figure">
<img src="chart.png" alt="Sales data for Q3 2024">
<figcaption>Figure 1: Quarterly sales by region.</figcaption>
</figure>
Using a different role like role="img" also triggers the error and can cause accessibility problems:
<figure role="img">
<img src="chart.png" alt="Sales data for Q3 2024">
<figcaption>Figure 1: Quarterly sales by region.</figcaption>
</figure>
Correct: <figure> with <figcaption> and no role
Simply remove the role attribute. The <figure> and <figcaption> elements handle semantics on their own:
<figure>
<img src="chart.png" alt="Sales data for Q3 2024">
<figcaption>Figure 1: Quarterly sales by region.</figcaption>
</figure>
Correct: <figure> without <figcaption> can use a role
If you have a <figure> without a <figcaption>, the restriction does not apply. In this case, you may use a role attribute if needed:
<figure role="img" aria-label="Sales data for Q3 2024">
<img src="chart.png" alt="">
</figure>
Correct: <figure> with <figcaption> containing other media
The fix applies regardless of the type of content inside the <figure>:
<figure>
<pre><code>const greeting = "Hello, world!";</code></pre>
<figcaption>A simple variable assignment in JavaScript.</figcaption>
</figure>
<figure>
<blockquote>
<p>The best way to predict the future is to invent it.</p>
</blockquote>
<figcaption>Alan Kay</figcaption>
</figure>
In every case, the <figcaption> provides the accessible name and descriptive context for the <figure>, making any role attribute unnecessary and non-conformant.
A <caption> element only belongs inside a <table>, as its first child, so the validator reports any <caption> start tag it finds anywhere else.
The <caption> element is the title of a table. When the HTML parser meets a <caption> tag outside a table, it drops the tag: the DOM gets no caption element, and whatever was inside it becomes plain content of the surrounding element. The parser drops the closing tag as well, so the same spot usually also gets a "Stray end tag caption" error.
A common source is an image caption written as <caption> around an <img>. WordPress's [caption] shortcode turns into this markup when its square brackets get swapped for angle brackets, for example after pasting content from one editor into another. To caption an image, use a <figure> with a <figcaption> inside it.
If the caption belongs to a table, move it inside the <table> as its first child. A <caption> inside the table but after the rows gets a different error, saying caption isn't allowed as a child of table in that context.
Invalid example
<div class="photo">
<caption>
<img src="harbor.jpg" alt="Fishing boats moored in a harbor">
Fishing boats in the harbor at sunrise.
</caption>
</div>
<caption>Opening hours</caption>
<table>
<tr>
<th>Monday</th>
<td>9:00 to 17:00</td>
</tr>
</table>
Valid example
<figure class="photo">
<img src="harbor.jpg" alt="Fishing boats moored in a harbor">
<figcaption>Fishing boats in the harbor at sunrise.</figcaption>
</figure>
<table>
<caption>Opening hours</caption>
<tr>
<th>Monday</th>
<td>9:00 to 17:00</td>
</tr>
</table>
Validate at scale.
Ship accessible websites, faster.
Automated HTML & accessibility validation for large sites. Check thousands of pages against WCAG guidelines and W3C standards in minutes, not days.
1K Weekly
1,000 monthly checks. Cancel anytime.
Get 1K Weekly →Join teams across 40+ countries