HTML Guides for details
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 open attribute on <details> is a boolean attribute, so it doesn't take values like "true" or "false".
A boolean attribute is on when it's present and off when it's absent. HTML allows only two values for one: the empty string (open="") or the attribute's own name (open="open"). Anything else, such as "true", "false", "1" or "yes", is invalid, and the validator quotes the value it found in the message.
Browsers only check whether the attribute is there, so open="false" still renders the <details> element expanded. To start it collapsed, leave the attribute out.
This often happens when a template prints a boolean variable straight into the attribute, as in open="{{ is_open }}". Output the bare open attribute when the condition is true and nothing when it's false. In JavaScript, set the open property instead (details.open = false). It takes a real boolean and adds or removes the attribute for you.
Invalid example
<details open="true">
<summary>Shipping details</summary>
<p>Orders ship within two business days.</p>
</details>
<details open="false">
<summary>Return policy</summary>
<p>Returns are accepted within 30 days.</p>
</details>
Valid example
<details open>
<summary>Shipping details</summary>
<p>Orders ship within two business days.</p>
</details>
<details>
<summary>Return policy</summary>
<p>Returns are accepted within 30 days.</p>
</details>
The first child of a <details> element must be a <summary>, and this error means the validator found something else there, or nothing at all.
The <summary> is the visible label of the disclosure widget, the part people click or tab to when they want to open or close the rest of the content. If it's missing, browsers make up a label of their own, usually "Details" in the browser's language. That tells sighted users and screen reader users nothing about what's inside.
A <summary> only counts when it comes first. Comments and whitespace before it are fine, but any element or text pushes it out of place. A <summary> after a paragraph, or wrapped in a <div>, leaves the <details> without one, and the validator adds a second error for the misplaced element: Element “summary” not allowed as child of element “details” in this context. (or … child of element “div” …). A second <summary> in the same <details> gets that error too.
Sometimes <details> ends up as a plain wrapper, for example around anchor targets or layout blocks, when nobody meant to build a collapsible section. In that case, replace it with a <div> or <section>. Otherwise, add a short <summary> as the first child, or move the existing one to the top.
Invalid example
<details>
<p>Orders ship within two business days.</p>
</details>
<details>
<p>Unused items can be returned within 30 days.</p>
<summary>Returns</summary>
</details>
Valid example
<details>
<summary>Shipping</summary>
<p>Orders ship within two business days.</p>
</details>
<details>
<summary>Returns</summary>
<p>Unused items can be returned within 30 days.</p>
</details>
A <details> element can hold text only after its <summary>, so any text before the <summary>, even an invisible character, is invalid.
The content model of <details> is one <summary> element followed by flow content, which means the <summary> has to come first. Spaces, tabs and line breaks between <details> and <summary> are fine. Any other character counts as text, and text in that position breaks the rule. Text after the <summary> is allowed, because it's part of the content the widget shows when it opens.
Invisible characters cause this error often. Pasting from a word processor or a rich text editor can leave a non-breaking space ( ) or a zero-width space (​, U+200B) right after the opening <details> tag. The page looks normal, but the validator still finds text there. Search the source for those characters and delete them.
If the text is meant as the label, move it into the <summary>. If it's part of the content, put it after the <summary>. A <details> with no <summary> at all also triggers this error, together with one saying the required <summary> child is missing.
Invalid example
<details>
Shipping information
<summary>Shipping</summary>
<p>Orders ship within two days.</p>
</details>
Valid example
<details>
<summary>Shipping information</summary>
<p>Orders ship within two days.</p>
</details>
A summary element that is the first summary child of a details element can't have a role attribute, whatever its value.
That summary is the control that opens and closes its details element. Browsers expose it as a button and report whether the details is open, and the ARIA in HTML specification allows no role on it. With role="button", the role only repeats what the browser already provides, and the validator also warns that it is unnecessary. Any other value, such as heading or link, tells screen readers the element is something other than the control that shows and hides the content.
This often comes from accordion markup that was moved onto details and summary. A script-driven accordion built from div or span elements needs role="button" and aria-expanded on each toggle. With details, the browser handles keyboard input and tracks the open state, so you can delete both attributes. The validator reports aria-expanded in its own message.
If role="heading" was there to mark the summary as a section title, put a heading element inside the summary instead. Its content model allows headings, but some screen readers announce only the button and drop the heading level, so test it with the ones your users rely on. If the control needs to act as a link or a tab, build a link or a tab widget instead of using details.
Invalid example
The summary toggles its details, so role="button" is not allowed on it.
<details open>
<summary role="button">Billing address</summary>
<p>Enter the address that appears on your card statement.</p>
</details>
Valid example
Without the role attribute, the browser exposes the summary as a button that opens and closes the section.
<details open>
<summary>Billing address</summary>
<p>Enter the address that appears on your card statement.</p>
</details>
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