Use Bootstrap button styles for reliable production actions: publish, review, and move work forward.
Use .btn for actions that submit, open, confirm, dismiss, or move work forward. Choose the native element from the action: use button for in-page behavior, a for real navigation, and input only when a form API requires it.
.btn
button
a
input
Choose one variant for emphasis and make the purpose visible in the label. Use .btn-primary for the main action in a small decision area, .btn-outline-* for quieter actions, and .btn-sm or .btn-lg only when the surrounding density changes.
.btn-primary
.btn-outline-*
.btn-sm
.btn-lg
Give icon-only buttons an aria-label, do not rely on color alone for destructive or success meaning, and set disabled while an action cannot run. If an a element triggers in-page behavior instead of navigating, add role="button" so assistive technology hears the right control type.
aria-label
disabled
role="button"
Use the primary button for the main action in a small decision area.
1<button class="btn btn-primary" type="button">Primary</button>
<button class="btn btn-primary" type="button">Primary</button>
An outlined button with no fill.
1<button class="btn btn-outline-secondary" type="button">Outline</button>
<button class="btn btn-outline-secondary" type="button">Outline</button>
A muted button for secondary actions.
1<button class="btn btn-secondary" type="button">Secondary</button>
<button class="btn btn-secondary" type="button">Secondary</button>
A transparent button with no background or border.
1<button class="btn btn-ghost" type="button">Ghost</button>
<button class="btn btn-ghost" type="button">Ghost</button>
A destructive button for dangerous actions.
1<button class="btn btn-danger" type="button">Destructive</button>
<button class="btn btn-danger" type="button">Destructive</button>
A button styled as a hyperlink.
1<button class="btn btn-link" type="button">Link</button>
<button class="btn btn-link" type="button">Link</button>
Use the size prop after choosing the button variant.
size
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26<div class="d-flex flex-column gap-3 flex-sm-row"> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-xs" type="button">Extra Small</button> <button class="btn btn-outline-secondary btn-icon-xs" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-sm" type="button">Small</button> <button class="btn btn-outline-secondary btn-icon-sm" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary" type="button">Default</button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-lg" type="button">Large</button> <button class="btn btn-outline-secondary btn-icon-lg" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div>
<div class="d-flex flex-column gap-3 flex-sm-row"> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-xs" type="button">Extra Small</button> <button class="btn btn-outline-secondary btn-icon-xs" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-sm" type="button">Small</button> <button class="btn btn-outline-secondary btn-icon-sm" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary" type="button">Default</button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="d-flex align-items-start gap-2"> <button class="btn btn-outline-secondary btn-lg" type="button">Large</button> <button class="btn btn-outline-secondary btn-icon-lg" type="button" aria-label="Submit"> <i class="lucide lucide-arrow-up-right" data-icon="inline-start" aria-hidden="true"></i> </button> </div> </div>
An icon-only button. Always provide an aria-label; the icon alone is not an accessible name.
1 2 3<button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Send"> <i class="lucide lucide-send" data-icon="inline-start" aria-hidden="true"></i> </button>
<button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Send"> <i class="lucide lucide-send" data-icon="inline-start" aria-hidden="true"></i> </button>
Remember to add the icon_start or icon_end parameter to the button for the correct spacing.
icon_start
icon_end
1 2 3 4 5 6 7 8 9 10<div class="d-flex flex-wrap gap-2"> <button class="btn btn-outline-secondary" type="button"> <i class="lucide lucide-git-branch" data-icon="inline-start" aria-hidden="true"></i> New Branch </button> <button class="btn btn-outline-secondary" type="button"> Fork <i class="lucide lucide-git-fork" data-icon="inline-end" aria-hidden="true"></i> </button> </div>
<div class="d-flex flex-wrap gap-2"> <button class="btn btn-outline-secondary" type="button"> <i class="lucide lucide-git-branch" data-icon="inline-start" aria-hidden="true"></i> New Branch </button> <button class="btn btn-outline-secondary" type="button"> Fork <i class="lucide lucide-git-fork" data-icon="inline-end" aria-hidden="true"></i> </button> </div>
Use disabled and loading states to make temporary limits and async work obvious to operators.
1 2 3 4 5 6 7 8<div class="d-flex flex-wrap gap-2"> <button class="btn btn-outline-secondary" type="button" disabled>Read-only mode</button> <button class="btn btn-secondary" type="button" disabled>Retry</button> <button class="btn btn-outline-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Saving </button> </div>
<div class="d-flex flex-wrap gap-2"> <button class="btn btn-outline-secondary" type="button" disabled>Read-only mode</button> <button class="btn btn-secondary" type="button" disabled>Retry</button> <button class="btn btn-outline-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Saving </button> </div>
Use the rounded-pill class to make the button rounded.
rounded-pill
1 2 3 4 5 6<div class="d-flex flex-wrap gap-2"> <button class="btn btn-primary rounded-pill" type="button">Get Started</button> <button class="btn btn-outline-secondary btn-icon rounded-pill" type="button" aria-label="Arrow up"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </button> </div>
<div class="d-flex flex-wrap gap-2"> <button class="btn btn-primary rounded-pill" type="button">Get Started</button> <button class="btn btn-outline-secondary btn-icon rounded-pill" type="button" aria-label="Arrow up"> <i class="lucide lucide-arrow-up" data-icon="inline-start" aria-hidden="true"></i> </button> </div>
Render a spinner inside the button to show a loading state. The loading parameter replaces the leading icon with a spinning loader and sets aria-busy.
loading
aria-busy
1 2 3 4 5 6 7 8 9 10<div class="d-flex flex-wrap gap-2"> <button class="btn btn-primary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Generating </button> <button class="btn btn-primary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Downloading </button> </div>
<div class="d-flex flex-wrap gap-2"> <button class="btn btn-primary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Generating </button> <button class="btn btn-primary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Downloading </button> </div>
d-grid gap-2 stacks actions with consistent spacing, while w-100 lets each button fill the available width. This is a layout choice, not a new button variant.
d-grid gap-2
w-100
1 2 3 4<div class="d-grid gap-2"> <button class="btn btn-primary w-100" type="button">Create workspace</button> <button class="btn btn-outline-secondary w-100" type="button">Invite collaborators</button> </div>
<div class="d-grid gap-2"> <button class="btn btn-primary w-100" type="button">Create workspace</button> <button class="btn btn-outline-secondary w-100" type="button">Invite collaborators</button> </div>
data-bs-toggle="button" keeps the pressed state synchronized. aria-pressed="false" marks an initial inactive state.
data-bs-toggle="button"
aria-pressed="false"
1<button class="btn btn-outline-secondary" type="button" data-bs-toggle="button" aria-pressed="false">Follow this ticket</button>
<button class="btn btn-outline-secondary" type="button" data-bs-toggle="button" aria-pressed="false">Follow this ticket</button>
Group adjacent actions that belong together. See the Button Group component for broader toolbar behavior.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40<div class="btn-toolbar gap-2" role="toolbar" aria-label="Message actions"> <div class="btn-group d-none d-sm-flex" role="group" aria-label="Navigation"> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Go back"> <i class="lucide lucide-arrow-left" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="btn-group" role="group" aria-label="Message review"> <button class="btn btn-outline-secondary" type="button">Archive</button> <button class="btn btn-outline-secondary" type="button">Report</button> </div> <div class="btn-group" role="group" aria-label="More actions"> <button class="btn btn-outline-secondary" type="button">Snooze</button> <button class="btn btn-outline-secondary btn-icon rounded-end" type="button" aria-label="More options" data-bs-toggle="dropdown" aria-expanded="false"> <i class="lucide lucide-ellipsis" data-icon="inline-start" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <i class="lucide lucide-mail-check" data-icon="inline-start" aria-hidden="true"></i> <span>Mark as handled</span> </button> </li> <li> <button class="dropdown-item" type="button"> <i class="lucide lucide-archive" data-icon="inline-start" aria-hidden="true"></i> <span>Move to archive</span> </button> </li> <li> <hr class="dropdown-divider"> </li> <li> <button class="dropdown-item" type="button" data-variant="destructive"> <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i> <span>Delete message</span> </button> </li> </ul> </div> </div>
<div class="btn-toolbar gap-2" role="toolbar" aria-label="Message actions"> <div class="btn-group d-none d-sm-flex" role="group" aria-label="Navigation"> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Go back"> <i class="lucide lucide-arrow-left" data-icon="inline-start" aria-hidden="true"></i> </button> </div> <div class="btn-group" role="group" aria-label="Message review"> <button class="btn btn-outline-secondary" type="button">Archive</button> <button class="btn btn-outline-secondary" type="button">Report</button> </div> <div class="btn-group" role="group" aria-label="More actions"> <button class="btn btn-outline-secondary" type="button">Snooze</button> <button class="btn btn-outline-secondary btn-icon rounded-end" type="button" aria-label="More options" data-bs-toggle="dropdown" aria-expanded="false"> <i class="lucide lucide-ellipsis" data-icon="inline-start" aria-hidden="true"></i> </button> <ul class="dropdown-menu dropdown-menu-end"> <li> <button class="dropdown-item" type="button"> <i class="lucide lucide-mail-check" data-icon="inline-start" aria-hidden="true"></i> <span>Mark as handled</span> </button> </li> <li> <button class="dropdown-item" type="button"> <i class="lucide lucide-archive" data-icon="inline-start" aria-hidden="true"></i> <span>Move to archive</span> </button> </li> <li> <hr class="dropdown-divider"> </li> <li> <button class="dropdown-item" type="button" data-variant="destructive"> <i class="lucide lucide-trash-2" data-icon="inline-start" aria-hidden="true"></i> <span>Delete message</span> </button> </li> </ul> </div> </div>
Use tabs to compare Arabic, Hebrew, and English button actions in RTL layout.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div class="d-flex flex-wrap align-items-center gap-2" dir="rtl"> <button class="btn btn-outline-secondary" type="button">زر</button> <button class="btn btn-danger" type="button">حذف</button> <button class="btn btn-outline-secondary" type="button"> إرسال <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="إضافة"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> جاري التحميل </button> </div>
<div class="d-flex flex-wrap align-items-center gap-2" dir="rtl"> <button class="btn btn-outline-secondary" type="button">زر</button> <button class="btn btn-danger" type="button">حذف</button> <button class="btn btn-outline-secondary" type="button"> إرسال <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="إضافة"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> جاري التحميل </button> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div class="d-flex flex-wrap align-items-center gap-2" dir="rtl"> <button class="btn btn-outline-secondary" type="button">כפתור</button> <button class="btn btn-danger" type="button">מחק</button> <button class="btn btn-outline-secondary" type="button"> שלח <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="הוסף"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> טוען </button> </div>
<div class="d-flex flex-wrap align-items-center gap-2" dir="rtl"> <button class="btn btn-outline-secondary" type="button">כפתור</button> <button class="btn btn-danger" type="button">מחק</button> <button class="btn btn-outline-secondary" type="button"> שלח <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="הוסף"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> טוען </button> </div>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15<div class="d-flex flex-wrap align-items-center gap-2" dir="ltr"> <button class="btn btn-outline-secondary" type="button">Button</button> <button class="btn btn-danger" type="button">Delete</button> <button class="btn btn-outline-secondary" type="button"> Send <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Add"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Loading </button> </div>
<div class="d-flex flex-wrap align-items-center gap-2" dir="ltr"> <button class="btn btn-outline-secondary" type="button">Button</button> <button class="btn btn-danger" type="button">Delete</button> <button class="btn btn-outline-secondary" type="button"> Send <i class="lucide lucide-arrow-right" data-icon="inline-end" aria-hidden="true"></i> </button> <button class="btn btn-outline-secondary btn-icon" type="button" aria-label="Add"> <i class="lucide lucide-plus" data-icon="inline-start" aria-hidden="true"></i> </button> <button class="btn btn-secondary" type="button" disabled aria-busy="true"> <i class="lucide lucide-loader-circle" data-icon="inline-start" aria-hidden="true"></i> Loading </button> </div>
For more detailed information, see the Bootstrap Button documentation.
No matching pages.
Restore the default appearance.