How to Create Bootstrap Buttons and Badges
Create Bootstrap 5.3 buttons and badges with practical examples for variants, sizes, counters, disabled states, and accessible markup.
In Bootstrap 5.3, create a button with .btn plus a variant such as .btn-primary. Create a badge with .badge and a color helper such as .text-bg-secondary. Use a native <button> for actions and an <a> for navigation.
1. Load Bootstrap 5.3
Use the version already installed in your project and match its documentation. The shortest standalone example uses the Bootstrap CDN. For an application, you can also install Bootstrap through a package manager and import the styles in your build.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Bootstrap buttons and badges</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<main class="container py-4">
<!-- Put the examples from this guide here. -->
</main>
</body>
</html>
The CDN version shown here follows Bootstrap’s 5.3 quick-start example. If your project already loads a different Bootstrap version, use its matching classes and documentation. See Bootstrap 5.3’s setup guide for CDN, package-manager, and module options.
2. Create a basic button
The .btn class supplies the shared button styling; add a variant to set its visual treatment.
<button type="button" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-secondary">Cancel</button>
Use a <button> when activating the control performs an action, such as saving a form or opening a dialog. Set type="button" for buttons that should not submit a form; use type="submit" when submission is intended.
Bootstrap also styles anchors and inputs. Choose an anchor when the control navigates to a URL. If an anchor performs an in-page action instead of navigation, Bootstrap recommends adding role="button".
3. Choose a button variant
Bootstrap 5.3 provides these standard variants:
| Class | Typical use |
|---|---|
btn-primary |
Prominent primary action |
btn-secondary |
Secondary action |
btn-success |
Success-related action or state |
btn-danger |
Destructive or danger-related action |
btn-warning |
Warning-related action |
btn-info |
Informational action |
btn-light |
Light treatment, often against a darker surface |
btn-dark |
Dark treatment |
btn-link |
Button behavior with link-like styling |
For example, <button class="btn btn-danger" type="button">Delete</button> uses the danger variant. Keep the action clear in the text: color by itself may not communicate meaning to everyone.
4. Use outline, size, and full-width styles
Outline buttons
Use .btn-outline-* when you want a less filled visual treatment:
<button type="button" class="btn btn-outline-primary">More details</button>
<a class="btn btn-outline-secondary" href="/settings">Settings</a>
Check the actual foreground and background pairing. Some light variants need a dark surface to maintain sufficient contrast.
Small and large buttons
<button type="button" class="btn btn-primary btn-sm">Small</button>
<button type="button" class="btn btn-primary">Default</button>
<button type="button" class="btn btn-primary btn-lg">Large</button>
For a custom size, adjust the button’s local CSS variables:
<button type="button" class="btn btn-primary custom-button">Custom size</button>
<style>
.custom-button {
--bs-btn-padding-y: 0.6rem;
--bs-btn-padding-x: 1.25rem;
--bs-btn-font-size: 1.1rem;
}
</style>
Full-width and stacked buttons
In Bootstrap 5.3, use display and gap utilities to make a responsive stack. The old Bootstrap 4 .btn-block class is not the 5.3 approach.
<div class="d-grid gap-2">
<button class="btn btn-primary" type="button">Save</button>
<button class="btn btn-secondary" type="button">Cancel</button>
</div>
To make the stack apply only at a breakpoint, combine responsive display utilities. For example, d-grid d-md-flex gap-2 stacks on narrow screens and switches to a flex row from the medium breakpoint.
5. Create badges
A badge is typically an inline label or count. Bootstrap 5.2 and later include .text-bg-* helpers that pair a background with a contrasting foreground color.
<span class="badge text-bg-secondary">New</span>
<span class="badge text-bg-success rounded-pill">Complete</span>
.rounded-pill gives the badge a pill shape. A badge scales with the font size of its immediate parent, so placing it in a heading or larger text also changes its relative size.
Older Bootstrap examples may combine .bg-* and .text-* utilities manually. When using an older Bootstrap release, check its documentation because .text-bg-* was introduced in Bootstrap 5.2.
6. Add a badge to a button
Put the badge inside the button and include visible text that explains what the number counts.
<button type="button" class="btn btn-primary">
Notifications <span class="badge text-bg-secondary">4</span>
</button>
Here, “Notifications” makes the counter’s context clear. If the number is ambiguous when read without its visual context, add screen-reader-only explanatory text:
<button type="button" class="btn btn-primary">
Inbox <span class="badge text-bg-secondary">4</span>
<span class="visually-hidden">unread messages</span>
</button>
For a counter positioned at the button’s corner, make the button a positioning context and place the badge with Bootstrap’s position utilities:
<button type="button" class="btn btn-primary position-relative">
Inbox
<span class="position-absolute top-0 start-100 translate-middle badge rounded-pill text-bg-danger">
4
<span class="visually-hidden">unread messages</span>
</span>
</button>
Use an inline counter when it should read as part of the button label. Use a corner badge when its position is part of the visual design, and ensure its meaning is still available to assistive technology.
7. Handle disabled and toggled states
Disabled controls
For a native button, use the HTML disabled attribute:
<button type="button" class="btn btn-primary" disabled>Saving…</button>
An anchor does not support the disabled attribute. Bootstrap recommends the .disabled class and aria-disabled="true", and suggests removing href when possible:
<a class="btn btn-primary disabled" aria-disabled="true">Unavailable</a>
If an anchor must retain an href, pointer-events: none alone does not prevent keyboard activation. Also remove it from the tab order with tabindex="-1" and use JavaScript to prevent the action. Prefer a native disabled button for an action that can be disabled.
Toggle buttons
To render a button as already pressed, mark its initial state with both .active and aria-pressed="true":
<button type="button" class="btn btn-primary active" aria-pressed="true">
Favorite
</button>
These attributes describe the initial state; they do not implement toggling. Add JavaScript to change the pressed state when the user activates the button, keeping the visual state and aria-pressed value in sync.
8. Accessibility checks
- Use visible action text that explains what the button does. Do not make color the only signal of meaning.
- Give badge counts context in visible text or with
.visually-hiddentext. - Use a semantic button for actions and an anchor for navigation.
- Check keyboard focus is visible. The base
.btnclass by itself does not provide the explicit focus and hover treatment supplied by a variant or custom styles. - Check contrast for the exact text and background combination in your page. A default palette does not guarantee every pairing meets contrast recommendations.
Bootstrap’s accessibility guidance emphasizes that accessible results depend on the markup, styling, and scripting used by the project. See the Bootstrap accessibility overview and the component docs for buttons and badges.
9. Troubleshoot common problems
| Symptom | Likely cause | Fix |
|---|---|---|
| Button looks like plain text | Bootstrap CSS did not load, or the .btn class is missing. |
Confirm the stylesheet URL and network response, then use .btn plus a variant class. |
| Classes appear to have no effect | The markup uses classes from a different Bootstrap version, or another stylesheet overrides them. | Match the docs to the version in the app and inspect computed styles for overrides. |
| Button submits a form unexpectedly | A button inside a form defaults to submit behavior. | Set type="button" for non-submit actions. |
| Badge color helper is not applied | .text-bg-* is unavailable in an older Bootstrap version. |
Use Bootstrap 5.2 or newer, or pair the older version’s background and text utilities manually. |
| Badge is too large or small | Badge sizing follows its immediate parent’s font size. | Check the parent typography or set a deliberate local font size. |
| Disabled link still activates by keyboard | pointer-events: none only addresses pointer interaction. |
Prefer a disabled button; otherwise remove href where possible, set tabindex="-1", and prevent activation in JavaScript. |
| Count is announced without context | The number has no accessible label or surrounding meaning. | Add visible context or a .visually-hidden description. |
| Button text is hard to read | The selected foreground and background have insufficient contrast. | Choose a better pairing and verify the rendered colors, especially for light variants. |
10. Rendering checks, performance, and reliability
Buttons and badges are CSS components, so their main implementation cost is loading the Bootstrap stylesheet already used by the page. Avoid adding another copy of Bootstrap solely for these components. For screenshot or visual regression checks, capture representative states: default, hover or focus, disabled, active, narrow viewport, and any badge overflow case. Keep the stylesheet version fixed between comparisons so a dependency update does not look like an application change.
When a browser screenshot is part of your workflow, check that the page has finished loading its CSS and fonts before capturing. For a one-request capture of a rendered page, ScreenshotNeo provides a website screenshot API and MCP server; its capture options include waiting for a selector, a delay, or network idle. Details and the full parameter list are in the ScreenshotNeo documentation.
Or skip the browser setup
Capture a rendered page with one GET request. See the ScreenshotNeo API docs for parameters such as viewport, full-page capture, and output format.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and removed, and known consent platforms, newsletter popups, and chat widgets can be removed before the shot; each step can be turned off.
- Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Response headers report the page verdict and billing status.
- An MCP server lets AI agents use screenshot, page-info, and PDF tools.
- 1,000 screenshots a month are free with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
11. FAQ
How do I create a Bootstrap button?
Use .btn with a variant, such as <button class="btn btn-primary" type="button">Save</button>.
How do I make a Bootstrap button outline or small?
Use a class such as .btn-outline-primary for an outline and add .btn-sm or .btn-lg for a built-in size.
How do I make a Bootstrap badge pill-shaped?
Add .rounded-pill to the badge, for example <span class="badge rounded-pill text-bg-success">Ready</span>.
Can a badge communicate a count by color alone?
Do not rely on color alone. Give the count visible context or provide explanatory screen-reader text.


