Skip to main content

Building a Bootstrap Accordion with the details/summary HTML tags in 2025

Posted on
Contents

A few years ago I wrote a short post about building a Bootstrap accordion using the <details> and <summary> HTML tags. The idea was to create a collapsible accordion without needing any JavaScript, relying solely on CSS for styling and the native functionality of the <details> element.

At the time it wasn’t possible to animate the opening and closing of the accordion (with CSS), but thanks to the relatively new ::details-content CSS pseudo-element with transitions we can do that now. So I’m revisiting that solution with an update with no need for JavaScript at all.

Note that the transition for now are only in Chrome/Edge, but I think support for Firefox and Safari is planned. If you’d prefer a more consistent experience across browsers, you might consider using the JavaScript-based solution in my original post.

Accordion Title 1

Last Friday night, yeah I think we broke the law, always say we're gonna stop. And on my 18th Birthday we got matching tattoos. All to me, give it all to me. Don't be a chicken boy, stop acting like a bitch. Suiting up for my crowning battle. Respect.

Accordion Title 2

Why don't you let me stop by? We freak in my jeep, Snoop Doggy Dogg on the stereo. Got a motel and built a fort out of sheets. It’s in the palm of your hand now baby. I was gonna hit it and quit it. Trying to connect the dots, don't know what to tell my boss.

Accordion Title 3

I know you get me so I let my walls come down, down. A perfect storm, perfect storm. Yes, we make angels cry, raining down on earth from up above. Do you ever feel like a plastic bag. The girl's a freak, she drive a jeep in Laguna Beach.

HTML

<div class="accordion border-bottom-0">
  <details class="accordion-item border-bottom-0">
    <summary class="accordion-button rounded-top">
      <div class="accordion-header user-select-none">Accordion Title 1</div>
    </summary>
    <div class="accordion-body border-bottom">
      <p>....</p>
    </div>
  </details>
  <details class="accordion-item border-bottom-0">
    <summary class="accordion-button">
      <div class="accordion-header user-select-none">Accordion Title 2</div>
    </summary>
    <div class="accordion-body border-bottom">
      <p>....</p>
    </div>
  </details>
  <details class="accordion-item">
    <summary class="accordion-button">
      <div class="accordion-header user-select-none">Accordion Title 3</div>
    </summary>
    <div class="accordion-body">
      <p>....</p>
    </div>
  </details>
</div>

Custom CSS

details.accordion-item:not([open]) .accordion-button {
  background-color: var(--bs-accordion-bg);
}

details.accordion-item:not([open]):last-of-type .accordion-button {
  border-bottom-right-radius: var(--bs-accordion-border-radius);
  border-bottom-left-radius: var(--bs-accordion-border-radius);
}

details.accordion-item:not([open]) .accordion-button::after {
  background-image: var(--bs-accordion-btn-active-icon);
  transform: unset;
}

details.accordion-item[open] .accordion-button::after {
  background-image: var(--bs-accordion-btn-icon);
  transform: var(--bs-accordion-btn-icon-transform);
}

/* Hide the default disclosure triangle on Safari */
summary.accordion-button::-webkit-details-marker {
  display: none;
}

@media (prefers-reduced-motion: no-preference) {
  details.accordion-item {
    interpolate-size: allow-keywords;
  }
}

details.accordion-item::details-content {
  block-size: 0;
  overflow-y: clip;
  transition: content-visibility 0.2s allow-discrete, block-size 0.2s;
}

details.accordion-item[open]::details-content {
  block-size: auto;
}

View demo & code

You might also like