HTMLDisclosure (<details>, <summary>)

<details> and <summary>

<details> and <summary> give you a native, zero-JavaScript disclosure widget: a section that can be toggled open and closed by the user. Browsers handle the expand/collapse behavior, keyboard interaction, and basic accessibility for free.
Basic Usage

details-basic.html

HTML
<details>
  <summary>What payment methods do you accept?</summary>
  <p>We accept all major credit cards, PayPal, and bank transfer.</p>
</details>
<summary> must be the first child of <details>—it's always visible and acts as the clickable control. Everything else inside <details> is the collapsible content, hidden until the user expands it.
The open Attribute
Add the boolean open attribute to render the details element already expanded on page load.

details-open.html

HTML
<details open>
  <summary>Shipping information</summary>
  <p>Orders ship within 2 business days via standard courier.</p>
</details>
Building an FAQ / Accordion

faq.html

HTML
<section aria-label="Frequently asked questions">
  <details>
    <summary>How do I reset my password?</summary>
    <p>Go to Settings &gt; Security and click "Reset Password."</p>
  </details>

  <details>
    <summary>Can I change my email address?</summary>
    <p>Yes, from the same Security page—changes require re-verification.</p>
  </details>

  <details>
    <summary>How do I delete my account?</summary>
    <p>Contact support; account deletion cannot be automated for safety.</p>
  </details>
</section>
Stack as many <details> elements as you need—each one opens and closes independently, with no JavaScript, event listeners, or ARIA attributes required to get correct keyboard and screen reader behavior.
Styling the Disclosure Marker
Browsers render a default triangle/arrow marker next to <summary>. You can restyle or remove it with CSS.

custom-marker.html

HTML
<style>
  /* Remove the default browser marker */
  summary {
    list-style: none;
    cursor: pointer;
  }
  summary::-webkit-details-marker {
    display: none;
  }

  /* Add a custom marker that rotates when open */
  summary::before {
    content: "▸";
    display: inline-block;
    margin-right: 6px;
    transition: transform 0.15s ease;
  }
  details[open] summary::before {
    transform: rotate(90deg);
  }
</style>

<details>
  <summary>Custom-styled disclosure</summary>
  <p>The marker above rotates when this is expanded.</p>
</details>
The toggle Event
If you do need to react to the open/close state in JavaScript—say, to lazy-load content or update analytics—<details> fires a toggle event every time its state changes.

toggle-event.html

HTML
<details id="pricing">
  <summary>View pricing details</summary>
  <p>Standard plan: $10/month. Pro plan: $25/month.</p>
</details>

<script>
  document.getElementById('pricing').addEventListener('toggle', (event) => {
    console.log('Details is now', event.target.open ? 'open' : 'closed');
  });
</script>

Attribute / API

Purpose

open

Boolean attribute—renders the element expanded by default

<summary>

Always-visible clickable label; must be the first child

toggle event

Fires whenever the open/closed state changes

Great fit for FAQs, changelogs, and “show more” content
Because it needs no JavaScript, <details>/<summary> is ideal anywhere you'd reach for an accordion component: FAQs, release notes, optional advanced settings, or long code samples you want collapsed by default.
Keyboard and screen reader support come for free
Clicking, pressing Enter/Space while <summary> is focused, and screen reader announcements of "expanded"/"collapsed" all work automatically—no ARIA attributes needed for the basic pattern.
Nesting Details for Multi-Level Disclosure
<details> elements can be nested, which is useful for hierarchical content like a table of contents or a settings panel with sub-options.

nested-details.html

HTML
<details>
  <summary>Advanced settings</summary>

  <details>
    <summary>Network</summary>
    <p>Configure proxy and timeout settings here.</p>
  </details>

  <details>
    <summary>Privacy</summary>
    <p>Control what data is shared with third parties.</p>
  </details>
</details>
Using name to Group Exclusive Details
Giving several <details> elements the same name attribute makes them behave like an exclusive accordion—opening one automatically closes the others in the same group, entirely natively.

exclusive-group.html

HTML
<details name="faq-group">
  <summary>What is your return policy?</summary>
  <p>Items can be returned within 30 days of purchase.</p>
</details>

<details name="faq-group">
  <summary>Do you ship internationally?</summary>
  <p>Yes, to most countries with a small additional fee.</p>
</details>
name grouping is a relatively recent addition
Check current browser support before relying on it for a critical interaction—older browsers simply ignore name and treat each <details> independently, which still degrades gracefully.
Combining with CSS content-visibility
Because collapsed <details> content is hidden from the render tree, it pairs well with lazy-loading patterns—browsers skip layout work for the collapsed content until it's opened, which can help performance on pages with many large collapsed sections.
  • <details>/<summary> is a native disclosure widget requiring zero JavaScript.

  • <summary> must be the first child of <details> and is always visible.

  • Add the open attribute to start expanded.

  • Style the default marker via the ::-webkit-details-marker pseudo-element or list-style.

  • Listen for the toggle event if you need to react to open/close changes in script.