Skip to content

Documentation

On this page

Collapse

Show and hide a panel with <details> and <summary> — no Collapse plugin. The trigger and the panel must be parent and child.

Sizes are minified and gzip. A plugin figure includes the Bootstrap runtime that plugin imports. Shipping every plugin is bootstrap.bundle.min.js at 23.3 KB gzip, not the sum of these rows.
What runs it JavaScript
Bootstrap 5.3 Collapse plugin 5.6 KB gzip
This repo details and summary 0 KB
Markup this component accepts. The full inventory is /components.json.
Avoid
  • No data-bs-target or href pointing at a distant id. A remote toggle needs your own script.
  • Do not put padding on .collapse itself; keep it on an inner wrapper such as .card-body.
  • Do not put hidden or hidden="until-found" on the panel inside <details>. Collapse is the disclosure; hidden="until-found" is for custom regions.

How it works

  • The widget is details.collapse. Add open to start expanded (replaces .collapse.show).
  • The trigger is the <summary>, typically with .btn. It has to live inside the <details> — there is no data-bs-target / href pointing at a distant id.
  • The browser exposes expanded/collapsed on the summary (replaces aria-expanded toggling from JavaScript). You can still add aria-controls if you give the panel an id, but it is not required.
  • ::details-content is the panel, and height (or width with .collapse-horizontal) transitions on it. That transition also needs interpolate-size: allow-keywords, which only Chromium has, so Firefox and Safari snap the panel open. Do not put padding on .collapse itself — keep it on an inner wrapper such as .card-body, same as Bootstrap.
  • The same name on several <details> elements makes the group exclusive (replaces data-bs-parent). See Accordion for that pattern.
  • <summary> is a button-like control, not an <a href>.
  • Closed panels stay in the document, so Find in page can match them (try archaeopteryx in the first example). Do not put hidden or display: none on the inner wrapper. For a custom region that is not a <details> panel, use hidden="until-found" with padding on a nested child. Bootstrap’s reboot would otherwise force display: none and break that attribute.

Example

Click the summary to show and hide the panel. .collapse hides content; [open] shows it; ::details-content handles the transition.

Toggle collapse
Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger. Find in page can still match it: the token is archaeopteryx.
HTML
<details class="collapse">
  <summary class="btn btn-primary mb-2">Toggle collapse</summary>
  <div class="card card-body">
    Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger. Find in page can still match it: the token is <strong>archaeopteryx</strong>.
  </div>
</details>

Horizontal

Add .collapse-horizontal to transition width instead of height, and set a width on the immediate child of the panel.

Toggle width collapse
This is some placeholder content for a horizontal collapse. It’s hidden by default and shown when triggered.
HTML
<div style="min-height: 120px;">
  <details class="collapse collapse-horizontal">
    <summary class="btn btn-primary mb-2">Toggle width collapse</summary>
    <div class="card card-body" style="width: 300px;">
      This is some placeholder content for a horizontal collapse. It’s hidden by default and shown when triggered.
    </div>
  </details>
</div>

Multiple toggles and targets

Each panel has its own summary. Independent details elements can be open at the same time.

Toggle first element
Some placeholder content for the first collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
Toggle second element
Some placeholder content for the second collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
HTML
<div class="row">
  <div class="col">
    <details class="collapse">
      <summary class="btn btn-primary mb-2">Toggle first element</summary>
      <div class="card card-body">
        Some placeholder content for the first collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
      </div>
    </details>
  </div>
  <div class="col">
    <details class="collapse">
      <summary class="btn btn-primary mb-2">Toggle second element</summary>
      <div class="card card-body">
        Some placeholder content for the second collapse component of this multi-collapse example. This panel is hidden by default but revealed when the user activates the relevant trigger.
      </div>
    </details>
  </div>
</div>

Find in page

hidden="until-found" hides a custom region until Find in page matches it. Collapse panels themselves stay on details — do not put hidden on the card.

Search this page for coelacanth.

HTML
<p>Search this page for <strong>coelacanth</strong>.</p>
<div hidden="until-found">
  <div class="card card-body">
    Find in page revealed this region. The token is <strong>coelacanth</strong>.
  </div>
</div>

Accessibility

<summary> is the control. The browser maps it to a disclosure, including Enter and Space. A hidden checkbox plus label is a checkbox, not a disclosure; that pattern is documented under Checkbox hack and is not used here.

Closed panels stay in the document. Find in page can match them. Do not add display: none on the inner wrapper.

Browser support

Three columns, not one baseline. The same row is on the overview.
No script Polyfill No fallback
details / summary. Trigger and panel must be parent/child. None Same interpolate-size limit as the accordion. .collapse-horizontal animates to max-content and depends on it too. The panel opens and closes everywhere.

Checkbox hack

A hidden checkbox plus a <label for> can toggle a sibling with :checked. That would let the trigger sit beside the panel (still not across the document), and several labels could share one id.

It is not worth a second Collapse variant, mainly for WCAG:

  • 4.1.2 Name, Role, Value. The control is exposed as a checkbox (“checked / not checked”), not as a disclosure (“expanded / collapsed”). <details> / <summary> already maps to that disclosure role. Fixing the checkbox with role="button" and live aria-expanded needs JavaScript, which is what the hack is meant to avoid.
  • 2.4.3 Focus Order / 2.4.7 Focus Visible. The real tab stop is the visually hidden input, so focus rings and AT cursor land off the visible button.
  • 1.3.1 Info and Relationships. A form control used as chrome is announced in forms mode and can be submitted with a surrounding form.
  • 2.1.1 Keyboard. A checkbox toggles with Space. A summary (and Bootstrap’s button trigger) also accepts Enter.

Keep remote or one-to-many toggles for JavaScript. For native collapse, <details> is the accessible control.