Skip to component content

Use Bootstrap button styles for reliable production actions: publish, review, and move work forward.

Usage

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.

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.

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.

Primary

Use the primary button for the main action in a small decision area.

Button
<button class="btn btn-primary" type="button">Primary</button>

Outline

An outlined button with no fill.

Button
<button class="btn btn-outline-secondary" type="button">Outline</button>

Secondary

A muted button for secondary actions.

Button
<button class="btn btn-secondary" type="button">Secondary</button>

Ghost

A transparent button with no background or border.

Button
<button class="btn btn-ghost" type="button">Ghost</button>

Destructive

A destructive button for dangerous actions.

Button
<button class="btn btn-danger" type="button">Destructive</button>

A button styled as a hyperlink.

Button

Size

Use the size prop after choosing the button variant.

Button
<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>

Icon

An icon-only button. Always provide an aria-label; the icon alone is not an accessible name.

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>

With Icon

Remember to add the icon_start or icon_end parameter to the button for the correct spacing.

Button
<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>

States

Use disabled and loading states to make temporary limits and async work obvious to operators.

Button
<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>

Rounded

Use the rounded-pill class to make the button rounded.

Button
<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>

Spinner

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.

Button
<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>

Block buttons

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.

Button
<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>

Toggle states

data-bs-toggle="button" keeps the pressed state synchronized. aria-pressed="false" marks an initial inactive state.

Button
<button class="btn btn-outline-secondary" type="button" data-bs-toggle="button" aria-pressed="false">Follow this ticket</button>

Button Group

Group adjacent actions that belong together. See the Button Group component for broader toolbar behavior.

Button

RTL

Use tabs to compare Arabic, Hebrew, and English button actions in RTL layout.

<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>
<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>

Component reference

Status
Accepted
Runtime
native HTML/CSS
Markup
Moo UI documented extension
Reference

For more detailed information, see the Bootstrap Button documentation.

Settings

Theme
Choose how Moo UI looks on this device.
Sidebar
Choose how the sidebar sits on the page.
Theme Builder
Tune catalog tokens and chart colors for this browser.
Base color
Theme color
Chart color
Heading font
Body font
Radius
Direction
Choose the reading direction. RTL flips the layout live.
Reset

Restore the default appearance.