
Quick answer: A Bootstrap 5 button is a button (or a) element with the btn class plus one style class — btn-primary, btn-secondary, btn-success, btn-danger, btn-warning, btn-info, btn-light, btn-dark or btn-link. Swap btn- for btn-outline- for an outlined version. Sizes are btn-lg and btn-sm, and grouping is btn-group. That is the entire vocabulary — this guide covers the parts people get wrong.
Part of our Bootstrap series. If the framework is not on your page yet, run through getting started with Bootstrap 5 first.
The basic set
<button type="button" class="btn btn-primary">Primary</button>
<button type="button" class="btn btn-secondary">Secondary</button>
<button type="button" class="btn btn-success">Save</button>
<button type="button" class="btn btn-danger">Delete</button>
<button type="button" class="btn btn-outline-primary">Outlined</button>
<!-- sizes -->
<button type="button" class="btn btn-primary btn-lg">Large</button>
<button type="button" class="btn btn-primary btn-sm">Small</button>Always set type="button" on a <button> that is not a submit control. Inside a <form> the default type is submit, so a stray toolbar button silently submits the form — one of the most common “why did my page reload” bugs. Use <a class="btn btn-primary"> for links styled as buttons, and <input type="submit" class="btn btn-primary"> for form submissions.
Two more utilities finish the set: btn-link renders a button that looks like an underlined link, and shape or utility classes such as rounded-pill and text-nowrap layer on top of any variant. Avoid stacking two colour classes on one button — the later rule in the stylesheet wins, which is rarely the one you expected.
Variations and states
| Goal | Markup |
|---|---|
| Full-width button | Wrap in <div class="d-grid"> — or add w-100 for a natural width |
| Disabled | disabled on a button; disabled + btn on an a also needs pointer-events:none via the .disabled class |
| Toggle (pressed state) | data-bs-toggle="button" plus aria-pressed |
| Button group | btn-group wrapper with a shared role="group" |
| Vertical group | btn-group-vertical |
| Checkbox / radio group | btn-check input + label — see the pattern below |
A checkbox button group keeps native form semantics: the input stays in the DOM and is only visually hidden, so your server still receives the value. This is the favourite way to build filter chips.
<div class="btn-group" role="group" aria-label="Filters">
<input type="checkbox" class="btn-check" id="f1" autocomplete="off">
<label class="btn btn-outline-primary" for="f1">Published</label>
<input type="checkbox" class="btn-check" id="f2" autocomplete="off">
<label class="btn btn-outline-primary" for="f2">Draft</label>
</div>Icons and buttons
Bootstrap ships no icon font; most projects add Bootstrap Icons and place the <i> inside the button with a small gap. The gap is easiest with a flex utility: <button class="btn btn-primary d-inline-flex align-items-center gap-2">. Keep icon-only buttons accessible by adding aria-label, since a screen reader has nothing else to announce.
Button, link or input?
Pick the element by behaviour, not by how it looks. Use a real <button> for anything that runs JavaScript — it is focusable, keyboard-activatable and announced correctly by assistive tech. Use an <a> when the control navigates to a URL, so middle-click and open-in-new-tab keep working. Use <button type="submit"> or an input to send a form. Styling any of the three with the btn class makes them look identical, so the choice is purely about semantics.
Common mistakes
- Missing
type="button". Toolbar buttons inside forms act as submit buttons by accident. - Using
btnwithout a variant. You get a plain, uncoloured button — always pair it with a colour class. - Styling
a.btnas disabled with thedisabledattribute. Anchors ignore it; use the.disabledclass and handle clicks in JS. - Stacking buttons without a gap. Add
gap-2to the parent flex container instead of margins on each button.
Buttons rarely live alone — they open dialogs (our Bootstrap modal guide), fire dropdown menus (the dropdown guide), and sit inside the layouts from the Bootstrap cards guide.
Want an instructor checking your UI work as you build it? Ampersand Academy teaches front-end development one-to-one, using your own project as the curriculum.
Frequently asked questions
How do I make a full-width Bootstrap button?
Wrap the button in a div with the d-grid class, or add w-100 to the button itself. d-grid is the recommended approach because it keeps the button’s margins intact when you stack several of them vertically.
Why does my Bootstrap button submit the form unexpectedly?
A button element inside a form defaults to type submit. Any button that is not meant to submit needs type set to button explicitly. This is the usual cause of an accidental page reload.
How do I disable a Bootstrap button?
Add the disabled attribute to a real button element. For an anchor styled as a button, add the disabled class instead and prevent clicks in JavaScript, because anchors do not respond to the disabled attribute.
What is the difference between btn-primary and btn-outline-primary?
btn-primary is a solid button filled with the theme colour and white text. btn-outline-primary has a coloured border and coloured text on a transparent background, filling in on hover. Use outline variants for secondary actions.
How do I group Bootstrap buttons together?
Wrap them in a div with the btn-group class and a role of group. Add btn-group-vertical to stack them instead, and use a btn-toolbar wrapper when you need several groups on one line.
