HTML details and summary

The <details> element creates a native, interactive disclosure widget that a user can open or close to reveal or hide content. The <summary> element defines the visible label — the part the user clicks — that toggles the rest of the content inside <details>. Together they give you a fully working “click to expand” accordion, FAQ answer, or spoiler panel with zero JavaScript and zero CSS, which is why they matter: they replace a pattern that used to require custom scripting with a single pair of semantic tags the browser already knows how to render, style, and make keyboard-accessible.

Overview / How it works

The <details> element is a flow-content container with a built-in open/closed state. In its closed state, the browser only shows the content of its first <summary> child; everything else inside <details> is present in the DOM but not rendered (similar in spirit to the hidden attribute, though it is the browser’s default UA stylesheet that does the hiding, not a global attribute). When the user clicks the summary — or focuses it with the keyboard and presses Enter or Space — the browser toggles an open boolean attribute on the <details> element itself. When open is present, all of the element’s content becomes visible; when it’s absent, only the summary shows.

Under the hood, the default rendering of <summary> includes a small triangular disclosure marker (▶ when closed, ▼ when open in most browsers) rendered via the browser’s internal ::marker-like mechanism, and the element is given display: list-item semantics in the default stylesheet. If you omit <summary> entirely, browsers synthesize a default label (commonly the text “Details”), so it’s best practice to always supply your own.

Semantically, <details> tells assistive technology and search engines “this is optional, collapsible supplementary content,” and <summary> is exposed to the accessibility tree with the ARIA role button (or similar disclosure role), automatically wired up with aria-expanded reflecting the open state. This is a big win over a hand-rolled JavaScript accordion, which usually requires the author to add all of that ARIA wiring manually.

Syntax

<details>
  <summary>Label the user clicks</summary>
  Hidden content revealed on click.
</details>
Part Description
<details> The container element. Accepts any flow content as children.
<summary> Must be the first child of <details>. Defines the always-visible, clickable label. At most one <summary> is used (a first one, if present, is honored; the element accepts only one as a direct summary child per spec).
open Boolean attribute on <details>. If present, the widget starts (or currently is) expanded. Omit it to start collapsed.
name An attribute on <details> (newer browsers) that groups multiple <details> elements so opening one automatically closes the others in the same named group — like radio buttons for accordions.

Examples

Example 1: A basic collapsible panel

<details>
  <summary>What is HTML?</summary>
  <p>HTML stands for HyperText Markup Language. It is the standard
  markup language used to structure content on the web.</p>
</details>

Result: The browser initially shows a single line reading “▶ What is HTML?” with a small triangle marker. Clicking anywhere on that line rotates the marker to point downward and reveals the paragraph below it, pushing any following content down the page. Clicking again collapses it.

This is the minimal, complete pattern: one <summary> as the label, followed by whatever content should stay hidden until requested.

Example 2: Starting open, and an FAQ list

<details open>
  <summary>Shipping information</summary>
  <p>Orders ship within 2 business days via standard courier.</p>
</details>

<details>
  <summary>Return policy</summary>
  <p>Items may be returned within 30 days with a receipt.</p>
</details>

<details>
  <summary>Warranty coverage</summary>
  <p>All products include a 1-year limited warranty.</p>
</details>

Result: Three stacked disclosure widgets render. Because the first one has the open attribute, its paragraph is visible immediately with a downward-pointing marker, while the other two show only their summary line with a right-pointing marker until clicked. This is a common pattern for building an FAQ page without any script: each question is a <summary> and each answer is the hidden body.

Example 3: Richer content and exclusive grouping with name

<details name="faq-group">
  <summary>How do I reset my password?</summary>
  <p>Go to <strong>Settings &gt; Security</strong> and select
  "Reset password". You will receive an email with a reset link.</p>
</details>

<details name="faq-group">
  <summary>How do I delete my account?</summary>
  <p>Contact support from the <strong>Help</strong> menu. Account
  deletion is permanent and cannot be undone.</p>
</details>

Result: Two disclosure widgets share the same name value, so they behave like a single-select accordion: opening the second one automatically closes the first, because only one member of a named group may be open at a time. Without the shared name, both could be open simultaneously.

How it works step by step / Under the hood

  1. The HTML parser builds a <details> DOM node and, as its first eligible child, a <summary> node; any remaining children (paragraphs, lists, images described in prose, etc.) become additional children of <details>.
  2. The browser’s default (user-agent) stylesheet renders the <summary> with a disclosure triangle and cursor: pointer, and by default collapses (does not render) the details’ other children unless the open attribute is present at parse time.
  3. The <summary> is inserted into the accessibility tree as an interactive, focusable control with an implicit button-like role and an aria-expanded state, so it is reachable via Tab and operable with Enter/Space without any tabindex or ARIA attributes from the author.
  4. On activation (click or keypress), the browser toggles the boolean open IDL/content attribute on the <details> element. This attribute change fires a toggle event on the element (useful if you later add JavaScript, though none is required for the core behavior) and triggers the browser to re-render the element, showing or hiding its non-summary children.
  5. If a name attribute links several <details> elements, the browser tracks that group and automatically closes sibling members when one opens — implemented natively, with no extra markup needed on the other elements beyond the shared name value.

Common Mistakes

Mistake 1: Putting <summary> anywhere but first

<details>
  <p>Some intro text.</p>
  <summary>Click to expand</summary>
</details>

Why it’s wrong: the <summary> must be the first child for the browser to use it as the visible label. When it isn’t first, browsers fall back to generating a default label (often literally “Details”), and your intended text becomes just another piece of hidden content, confusing readers who never see it until they’ve already opened the panel.

<details>
  <summary>Click to expand</summary>
  <p>Some intro text.</p>
</details>

Mistake 2: Relying on <details> for critical, always-needed content

Why it’s wrong: content hidden inside a closed <details> is not visible on page load and, in some setups, may be weighted differently by search engines or missed by users skimming quickly. Don’t hide essential instructions, form fields, or safety warnings behind a disclosure widget purely for visual tidiness — reserve <details> for genuinely optional or supplementary information, like FAQs, changelogs, or “read more” details.

Mistake 3: Nesting interactive controls awkwardly inside <summary>

<details>
  <summary><button>Expand</button></summary>
  <p>Content</p>
</details>

Why it’s wrong: <summary> is already an interactive, clickable, keyboard-focusable control. Nesting another interactive element like <button> inside it creates overlapping, conflicting interactive regions (invalid interactive-content nesting) and confuses keyboard and screen-reader users about what actually toggles the panel. Just style plain text or inline elements like <strong> inside <summary> instead.

Best Practices

  • Always include an explicit <summary> as the first child so the label is meaningful and under your control, not browser-generated.
  • Reserve <details> for genuinely optional/supplementary content (FAQs, extra notes, code samples, changelogs) rather than essential page content.
  • Use the name attribute to group related <details> elements into an exclusive accordion instead of writing custom JavaScript to close siblings.
  • Keep <summary> text short and descriptive — it’s the only thing visible when collapsed, and it’s what screen reader users hear first.
  • Avoid nesting other interactive/focusable elements (buttons, links, form controls) directly inside <summary>.
  • Remember that visual styling (colors, custom markers, spacing) belongs in CSS, not inline attributes — this lesson covers only the structural/semantic behavior.
  • Test with the keyboard: Tab to the summary and press Enter/Space to confirm it toggles as expected, since some users never use a mouse.

Practice Exercises

  1. Build a small FAQ section with three <details> elements, each with a question in <summary> and an answer paragraph inside. Make the first one open by default using the open attribute.
  2. Add a shared name attribute to all three <details> elements from the previous exercise so only one answer can be expanded at a time. Verify (by reasoning through the behavior) what happens when a second one is opened while the first is still open.
  3. Write a <details> element containing a nested list (<ul>) of three items as its hidden content, with the summary reading “Show ingredients”. Make sure the <summary> is the very first child.

Summary

  • <details> creates a native, no-JavaScript collapsible/expandable widget.
  • <summary> must be the first child of <details> and defines the always-visible clickable label.
  • The boolean open attribute controls (and reflects) whether the widget is expanded.
  • The name attribute groups multiple <details> elements into an exclusive accordion where opening one closes the others.
  • Browsers automatically expose <summary> as a focusable, keyboard-operable control with proper accessibility semantics, including aria-expanded state.
  • Use this pattern for optional/supplementary content like FAQs, not for essential page content.