0Support

HTML details playground

Explore details with controls to edit each summary and content, add new blocks, and test the name attribute for JavaScript-free exclusive accordions.

Read the guide

Ask AI

HTML details playground

Response generated with openai/gpt-5.4-nano. AI can make mistakes. Always review the result.
First details

The details element can show or hide additional content natively.

Second details

The summary element defines the visible text that toggles each disclosure block.

HTML
<details dir="ltr">
  <summary>First details</summary>
  <p>The details element can show or hide additional content natively.</p>
</details>

<details dir="ltr">
  <summary>Second details</summary>
  <p>The summary element defines the visible text that toggles each disclosure block.</p>
</details>

Educational guide to details and summary

Reveal content with native HTML

A secondary explanation can wait until someone needs it. Learn how details and summary reveal content in the flow, when to group it into an exclusive accordion, and how to preserve semantics, keyboard access, and focus.

Back to playground

Mental model

The same block switches between closed and open. Its content takes up space on the page; it does not appear in a floating layer.

One label, two statesStatic diagram; the following recipes let you test the actual toggle.Without open only summary appears; the content stays collapsed.With open, summary and the following content are shown and take up space.

details contains a summary followed by expandable content: paragraphs, lists, or other flow elements. The first summary is the label that remains visible and activates the toggle. Write a name that helps people decide whether to open it.

open is a Boolean attribute: its presence opens the block. open="false" also opens it; to close it, remove the attribute or set details.open = false. The browser updates open when summary is activated, without a custom click listener.

Opening pushes subsequent content down; closing removes the panel from the normal reading and focus journey. There is no top layer, inert background, or Escape dismissal. Keep information needed to complete the task visible.

Independent or exclusive

Choose according to what people need to read: comparing two answers and reducing occupied space are different goals.

Without name, each block opens independently and several can remain open. This helps compare information or browse questions without losing previous answers. The first recipe initially opens one block with open.

A shared non-empty name creates an exclusive group: opening one member closes the previous one; activating it again can leave all members closed. No JavaScript is needed to enforce this relationship in supporting browsers.

Members are grouped by name within the same tree, even when they are not siblings. Use a distinct name for each set and keep members together under a heading. Do not nest one member inside another with the same name or declare multiple open members. This guide uses a different name from the playground.

Read two answers together

When will my order arrive?

Standard delivery takes two to four working days after dispatch.

How do I prepare a return?

Keep the packaging and include your order number when requesting a return.

Open the second answer: the first stays open. Each summary controls its own content. HTML and CSS provide this behavior.
Read two answers together
<div id="details-guide-independent">
  <details open>
    <summary>When will my order arrive?</summary>
    <p>Standard delivery takes two to four working days after dispatch.</p>
  </details>
  <details>
    <summary>How do I prepare a return?</summary>
    <p>Keep the packaging and include your order number when requesting a return.</p>
  </details>
</div>
:root {
  color-scheme: light dark;
}

#details-guide-independent {
  display: grid;
  gap: 1rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
  font-size: 1rem;
  line-height: 1.65;
  overflow-wrap: anywhere;

  details {
    min-inline-size: 0;
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;
    background: light-dark(oklch(0.98 0.005 95), oklch(0.16 0.02 260));
  }

  summary {
    display: list-item;
    min-block-size: 2.75rem;
    padding: 0.75rem 1rem;
    font-weight: 800;
    cursor: pointer;

    &:focus-visible {
      outline: 3px dashed light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      outline-offset: 3px;
    }
  }

  details[open] > summary {
    border-block-end: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
  }

  p {
    margin: 0;
    padding: 1rem;
  }
}

Read one answer at a time

When will my order arrive?

Standard delivery takes two to four working days after dispatch.

How do I prepare a return?

Keep the packaging and include your order number when requesting a return.

Open the second answer: with name support, the first closes. You can close the second too. Without that support, both work as independent disclosures.
Read one answer at a time
<div id="details-guide-exclusive">
  <details name="details-guide-exclusive" open>
    <summary>When will my order arrive?</summary>
    <p>Standard delivery takes two to four working days after dispatch.</p>
  </details>
  <details name="details-guide-exclusive">
    <summary>How do I prepare a return?</summary>
    <p>Keep the packaging and include your order number when requesting a return.</p>
  </details>
</div>
:root {
  color-scheme: light dark;
}

#details-guide-exclusive {
  display: grid;
  gap: 1rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
  font-size: 1rem;
  line-height: 1.65;
  overflow-wrap: anywhere;

  details {
    min-inline-size: 0;
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;
    background: light-dark(oklch(0.98 0.005 95), oklch(0.16 0.02 260));
  }

  summary {
    display: list-item;
    min-block-size: 2.75rem;
    padding: 0.75rem 1rem;
    font-weight: 800;
    cursor: pointer;

    &:focus-visible {
      outline: 3px dashed light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      outline-offset: 3px;
    }
  }

  details[open] > summary {
    border-block-end: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
  }

  p {
    margin: 0;
    padding: 1rem;
  }
}

Semantics, keyboard, and focus

summary already provides the native control. Styling can help people discover it while preserving its behavior.

Reach summary with Tab and try Enter and Space to open and close it. Focus stays on summary when activated; with the panel open, Tab can continue to inner links or fields. The name attribute does not add arrow-key navigation between labels.

Keep native semantics: do not redundantly add role="button", tabindex="0", or aria-expanded to summary. The browser exposes the expanded state. Avoid links and buttons inside the label so actions do not compete with the toggle; place them in the content.

A heading inside summary is permitted HTML, but its role can vary in assistive technology. These recipes use plain text and put the group title outside. Check names, state, and reading in your browser and screen reader combinations.

If a script closes a block while focus is inside, move it to a visible, logical destination such as its summary. Do not force focus into the content on every opening or turn the block into a Tab trap. Let people choose how to explore it.

Style while preserving the control

Start with a native marker, a comfortable activation area, and a focus outline. Animation can be added later.

summary uses display: list-item by default and keeps its disclosure marker. Changing it to flex or grid can remove that marker. These recipes keep list-item, padding, and visible focus; [open] adds a border separating label and content.

You can adjust summary::marker, but it does not accept all box properties and customization varies across browsers. If replacing it with your own icon, keep a visible opening cue and test Safari, keyboard access, and forced colors. Removing the triangle without another cue makes the control harder to discover.

details[open] covers these recipes’ state. :open and ::details-content are enhancements with their own support; the latter selects content without summary. Check each selector with @supports selector(...) before adding an enhancement and preserve the base toggle.

Adding transition to details does not animate content height by itself. An opening transition needs sizing and visibility handling, with support separate from ::details-content. These recipes do not animate; if you add motion, respect prefers-reduced-motion and avoid hiding content or focus with fixed heights.

Explore ::details-content

Observe state with toggle

JavaScript adds effects associated with state; the browser remains responsible for opening and closing.

toggle is sent to details after its state changes. It is neither cancelable nor bubbling: listen directly on each block, or use capture when needed. Read details.open for the current state and synchronize the observer when initializing.

Several rapid changes to open may be coalesced into one event. Do not use toggle as a click counter or change open again in a summary click listener: you could reverse the native action twice. In an accordion, opening one member can also produce toggle on the closing member.

A local state observer

View packing instructions

Protect fragile items and avoid empty spaces inside the box.

Observed state: The observer needs JavaScript.

Activate summary and compare the panel with the written state below. The script only reads open and updates this recipe’s output. Without JavaScript the disclosure works and the output explains that the observer needs it.
A local state observer
<div id="details-guide-events">
  <details id="details-guide-events-disclosure">
    <summary>View packing instructions</summary>
    <p>Protect fragile items and avoid empty spaces inside the box.</p>
  </details>
  <p class="status">
    Observed state:
    <output id="details-guide-events-status" data-opened="Open" data-closed="Closed">The observer needs JavaScript.</output>
  </p>
</div>
:root {
  color-scheme: light dark;
}

#details-guide-events {
  display: grid;
  gap: 1rem;
  color: light-dark(oklch(0.22 0.01 95), oklch(0.95 0.01 95));
  font-size: 1rem;
  line-height: 1.65;
  overflow-wrap: anywhere;

  details {
    min-inline-size: 0;
    border: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
    border-radius: 16px;
    corner-shape: squircle;
    background: light-dark(oklch(0.98 0.005 95), oklch(0.16 0.02 260));
  }

  summary {
    display: list-item;
    min-block-size: 2.75rem;
    padding: 0.75rem 1rem;
    font-weight: 800;
    cursor: pointer;

    &:focus-visible {
      outline: 3px dashed light-dark(oklch(0.46 0.14 261), oklch(0.82 0.18 261));
      outline-offset: 3px;
    }
  }

  details[open] > summary {
    border-block-end: 1px solid light-dark(oklch(0.84 0.01 95), oklch(0.36 0.024 260));
  }

  p {
    margin: 0;
    padding: 1rem;
  }
}
(() => {
  const disclosure = document.getElementById('details-guide-events-disclosure');
  const status = document.getElementById('details-guide-events-status');
  if (!disclosure || !status || disclosure.dataset.bound) return;
  disclosure.dataset.bound = 'true';

  const update = () => {
    status.textContent = disclosure.open
      ? status.dataset.opened
      : status.dataset.closed;
  };
  disclosure.addEventListener('toggle', update);
  update();
})();

Choose the pattern

Revealing an explanation, presenting temporary help, and asking for a decision need different journeys.

details · content in the flow

FAQs or secondary explanations belonging to a section. Avoid collapsing essential instructions, errors, or content that needs continuous comparison. name is optional: saving space does not always make reading easier.

Popover · temporary content

Contextual help or actions in the top layer without blocking the document. It provides its own dismissal modes; details takes up space in its section and does not close on outside clicks.

dialog · a task in a window

A confirmation or interaction with explicit opening and closing. showModal() can block the rest of the document. An open details does not create modality or enforce a decision.

details also does not replace tabs, a command menu, or an options list. Those patterns have different relationships and keys. A form can live inside, but collapsing it does not disable fields or remove validation: avoid hiding errors or required fields without a clear way to find them.

Common mistakes

Connect the symptom to state and structure before adding logic.

open="false" keeps it open

What you expected
Render a closed block.
Why it happens
open is Boolean; any present value represents an open state.
How to fix it
Omit open in HTML or set details.open = false in JavaScript.

Another accordion loses its answer

What you expected
Keep two question sets independent.
Why it happens
Both use the same name within the same tree.
How to fix it
Give each set a different name and group its members semantically.

One click opens and closes it again

What you expected
One toggle when summary is activated.
Why it happens
A click listener reverses open in addition to the native action.
How to fix it
Remove manual toggling and use toggle only to observe state.

The label no longer looks interactive

What you expected
Discover the disclosure and operate it with a keyboard.
Why it happens
CSS removes the marker and focus, or summary is not the first child.
How to fix it
Place summary first and keep an opening cue and visible focus.

Support and compatibility

The basic disclosure and its extensions have different compatibility statuses.

details, summary, and open are Widely Available. Native opening needs no JavaScript. The card describes general compatibility; it does not certify this browser or the assistive technology journey.

name is Newly Available since September 3, 2024: Chrome/Edge 120, Firefox 130, and Safari 17.2. Without exclusivity, the recipe preserves content and independent toggling. This degradation works when showing several answers together remains useful.

"name" in HTMLDetailsElement.prototype detects the reflected property in supporting browsers; writing the attribute does not verify exclusivity. If your application requires only one open member, check the group behavior and choose its fallback. These recipes accept independent opening and add no polyfill.

Do not infer search behavior from base support: finding text in a closed details and revealing it depends on the browser and version; MDN records scrolling limits in Safari. Also check links to inner content in your actual targets. Hiding content in the DOM does not make it private.

Support for :open, ::details-content, and animation techniques is checked separately. The example uses [open] and a native marker to work without them. All editorial content and HTML/CSS examples are served in full without JavaScript.