Bootstrap Collapse: Show and Hide Content in Bootstrap 5
Bootstrap’s collapse component shows and hides a block of content with a short sliding animation: a “Show more” section, a filter panel, extra form fields, or the menu in a collapsed navbar. It’s the plugin behind the accordion and the mobile navbar, and it works from data attributes with no code. This guide covers the markup, toggling with buttons or links, horizontal collapse, controlling several elements at once, the JavaScript API, and common problems. Everything is for Bootstrap 5.3.
A working collapse
<button class="btn btn-outline-primary" type="button" data-bs-toggle="collapse"
data-bs-target="#more-details" aria-expanded="false" aria-controls="more-details">
Show details
</button>
<div class="collapse" id="more-details">
<div class="card card-body mt-2">
The Pro plan includes unlimited projects, priority support, and custom domains.
</div>
</div>
| Part | Job |
|---|---|
data-bs-toggle="collapse" |
Makes the button open and close the target |
data-bs-target="#id" |
Points to the element to collapse |
.collapse |
Hides the element until it’s opened |
.collapse.show |
The element starts open |
aria-expanded, aria-controls |
Tell screen readers whether it’s open and what it controls |
Load Bootstrap’s JavaScript (bootstrap.bundle.min.js or bootstrap.min.js). Bootstrap keeps aria-expanded and the button’s collapsed class in sync as the content opens and closes.
Put padding and borders on an element inside the collapsed one, as with the card above, not on the .collapse element itself. Padding on the collapsing element makes the animation jump.
Toggle with a link
A link works too, with the target in its href:
<a class="link-primary" data-bs-toggle="collapse" href="#faq-answer" role="button"
aria-expanded="false" aria-controls="faq-answer">How do refunds work?</a>
<div class="collapse" id="faq-answer">
<p class="mt-2">Refunds go back to the original payment method within 5 business days.</p>
</div>
role="button" tells screen readers it acts as a button rather than navigating.
Change the button text when it opens
Swap the label with the collapsed class Bootstrap toggles on the button:
<button class="btn btn-link collapsed" type="button" data-bs-toggle="collapse"
data-bs-target="#extra" aria-expanded="false" aria-controls="extra">
<span class="when-closed">Show more</span>
<span class="when-open">Show less</span>
</button>
.collapsed .when-open, :not(.collapsed) > .when-closed { display: none; }
Start the button with the collapsed class when the content starts closed. Rotate an arrow icon the same way: .btn .bi-chevron-down { transition: transform .2s; } .btn:not(.collapsed) .bi-chevron-down { transform: rotate(180deg); }.
Horizontal collapse
collapse-horizontal animates the width instead of the height. The inner element needs a fixed width:
<button class="btn btn-primary" type="button" data-bs-toggle="collapse"
data-bs-target="#filters" aria-expanded="false" aria-controls="filters">Filters</button>
<div class="collapse collapse-horizontal" id="filters">
<div class="card card-body" style="width: 280px;">Price, size, and color filters</div>
</div>
Control several elements at once
One button can toggle several elements by using a class selector as the target:
<button class="btn btn-secondary" type="button" data-bs-toggle="collapse"
data-bs-target=".billing-fields" aria-expanded="false">Add billing details</button>
<div class="collapse billing-fields">...</div>
<div class="collapse billing-fields">...</div>
And several buttons can control the same element.
Only one open at a time
Give each collapsible element data-bs-parent pointing to a shared wrapper, and opening one closes the others:
<div id="plans">
<button class="btn btn-link" data-bs-toggle="collapse" data-bs-target="#plan-free" aria-expanded="false">Free</button>
<button class="btn btn-link" data-bs-toggle="collapse" data-bs-target="#plan-pro" aria-expanded="false">Pro</button>
<div class="collapse" id="plan-free" data-bs-parent="#plans">Free plan details</div>
<div class="collapse" id="plan-pro" data-bs-parent="#plans">Pro plan details</div>
</div>
For headings and panels styled together, the Bootstrap accordion is this same pattern with ready-made styles.
Collapse in forms
Show extra fields only when they’re needed, for example a company name when “Business account” is ticked:
<div class="form-check">
<input class="form-check-input" type="checkbox" id="is-business">
<label class="form-check-label" for="is-business">Business account</label>
</div>
<div class="collapse" id="business-fields">
<label for="company" class="form-label mt-2">Company name</label>
<input type="text" class="form-control" id="company">
</div>
const fields = bootstrap.Collapse.getOrCreateInstance('#business-fields', { toggle: false })
document.querySelector('#is-business').addEventListener('change', e => {
e.target.checked ? fields.show() : fields.hide()
})
toggle: false stops the panel from toggling when the instance is created. More form patterns are in the Bootstrap forms guide.
The JavaScript API
const panel = bootstrap.Collapse.getOrCreateInstance('#more-details', { toggle: false })
panel.show()
panel.hide()
panel.toggle()
| Event | Fires |
|---|---|
show.bs.collapse |
When opening starts; event.preventDefault() cancels it |
shown.bs.collapse |
When the content is fully open |
hide.bs.collapse |
When closing starts |
hidden.bs.collapse |
When the content is fully hidden |
Use shown.bs.collapse to load content on first open, or to focus a field inside it.
Collapse or details element?
HTML’s <details> and <summary> open and close with no JavaScript and work in every modern browser. Use them for simple show-and-hide text. Use Bootstrap’s collapse when you want the animation, buttons styled like the rest of the site, a trigger that’s separate from the content, or one-open-at-a-time groups.
Common problems
Clicking does nothing. Bootstrap’s JavaScript isn’t loaded, or data-bs-target doesn’t match the element’s id. Check the browser console.
The animation jumps or stutters. The .collapse element has padding or margin. Move it to an inner element.
It opens and immediately closes. Bootstrap’s JavaScript is loaded twice, or both a data attribute and your own click handler toggle it.
Bootstrap 4 markup doesn’t work. Rename data-toggle and data-target to data-bs-toggle and data-bs-target.
FAQ
How do I use collapse in Bootstrap 5?
Add class="collapse" and an id to the content, and a button with data-bs-toggle="collapse" and data-bs-target="#that-id". With Bootstrap’s JavaScript loaded, the button shows and hides the content with an animation.
How do I make a Bootstrap collapse open by default?
Add the show class to the collapsible element (class="collapse show") and set aria-expanded="true" on its button, without the collapsed class.
How do I collapse content horizontally in Bootstrap?
Add collapse-horizontal to the .collapse element and give its child a fixed width, such as style="width: 280px". The content then slides open sideways.
How do I toggle Bootstrap collapse with JavaScript?
Create an instance with bootstrap.Collapse.getOrCreateInstance('#id', { toggle: false }), then call show(), hide(), or toggle(). Listen for shown.bs.collapse and hidden.bs.collapse to run code after it opens or closes.
Why does my Bootstrap collapse animation jump?
The element with the collapse class has padding, margin, or a border. Bootstrap animates its height, so move the spacing to an element inside it.
Try it in the builder
Make these changes visually with a live preview, then export clean Bootstrap Sass or CSS.
Open the Builder