Bootstrap Dropdown: 16 Examples of Menus, Forms and Filters

The Bootstrap dropdown does something on touch screens that never shows up in the markup. Open a menu and the plugin adds empty mouseover handlers to the body's direct children, an iOS workaround that lets a tap outside close it.

Below are 16 Bootstrap dropdown examples you can copy, followed by a guide to setup, options, accessibility and menus that get cut off.

By Bogdan Sandu ยท Updated October 29, 2026

Every example runs on Bootstrap 5.3.8 from the jsDelivr CDN. Add these tags to your page, then paste an example's HTML, CSS and JS.

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-sRIl4kxILFvY47J16cr9ZwB07vP4J8+LH7qKQnuqkuIAvNWLzeN8tE5YBujZqJLB" crossorigin="anonymous">
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.13.2/font/bootstrap-icons.min.css" rel="stylesheet" integrity="sha384-nWN3KqaaVcbEsCjLSV+2jMjh62Iny/+mN3srM8TZeM8N6aj7eDl5wwYggjAJ4/sJ" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.8/dist/js/bootstrap.bundle.min.js" integrity="sha384-FKyoEForCGlyvwx9Hj09JcYn3nv7wiPVlz7YYwJrWVcXK/BmnVDxM+D2scQbITxI" crossorigin="anonymous"></script>

Menus for everyday app UI

Account, row action, notification and language menus: the dropdowns almost every dashboard needs. Each one is the stock dropdown markup with headers, dividers, icons and a few lines of script where state has to change.

Account menu with avatar

  • dropdown-menu-end
  • dropdown-header
  • dropdown-divider
  • dropdown-item-text

Click the toggle to open the menu.

An avatar button opens a right-aligned menu with a profile block, grouped links under dropdown-header labels and a sign-out item set apart by dividers. The avatar is plain initials on a colored circle, and the toggle has an aria-label because the visible text is only two letters.

View code
<div class="bdd-acct d-flex align-items-center justify-content-between bg-body border rounded-3 px-3 py-2 shadow-sm">
  <span class="fw-semibold">Larkspur Studio</span>
  <div class="dropdown">
    <button type="button" class="btn bdd-acct-toggle d-flex align-items-center gap-2 p-1 pe-2 rounded-pill dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Account menu for Maya Ortiz">
      <span class="bdd-avatar rounded-circle d-inline-flex align-items-center justify-content-center" aria-hidden="true">MO</span>
    </button>
    <ul class="dropdown-menu dropdown-menu-end shadow bdd-acct-menu">
      <li class="dropdown-item-text">
        <span class="d-block fw-semibold">Maya Ortiz</span>
        <span class="d-block small text-body-secondary">maya@larkspur.example</span>
      </li>
      <li><hr class="dropdown-divider"></li>
      <li><h6 class="dropdown-header">Workspace</h6></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-person me-2" aria-hidden="true"></i>Profile</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-credit-card me-2" aria-hidden="true"></i>Billing</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-gear me-2" aria-hidden="true"></i>Settings</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><button type="button" class="dropdown-item text-danger"><i class="bi bi-box-arrow-right me-2" aria-hidden="true"></i>Sign out</button></li>
    </ul>
  </div>
</div>

Kebab action menu on a table row

  • table-responsive
  • popperConfig
  • strategy: fixed
  • aria-label

Click the toggle to open the menu.

Each row has an icon-only kebab button with its own aria-label. The table sits in .table-responsive, which clips an absolutely positioned menu, so the script creates each dropdown with a popperConfig function that keeps Bootstrap's defaults and switches Popper to the fixed strategy.

View code
<div class="bdd-rows w-100 bg-body border rounded-3 shadow-sm">
  <div class="table-responsive">
    <table class="table align-middle mb-0">
      <thead>
        <tr><th scope="col">Invoice</th><th scope="col" class="d-none d-sm-table-cell">Client</th><th scope="col" class="text-end">Amount</th><th scope="col"><span class="visually-hidden">Actions</span></th></tr>
      </thead>
      <tbody>
        <tr>
          <td class="fw-semibold">INV-1042</td><td class="d-none d-sm-table-cell">Fernhill Market</td><td class="text-end">$1,280</td>
          <td class="text-end">
            <div class="dropdown">
              <button type="button" class="btn btn-link link-secondary bdd-kebab" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Actions for INV-1042"><i class="bi bi-three-dots-vertical" aria-hidden="true"></i></button>
              <ul class="dropdown-menu dropdown-menu-end shadow-sm">
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Opened"><i class="bi bi-eye me-2" aria-hidden="true"></i>View</button></li>
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Duplicated"><i class="bi bi-copy me-2" aria-hidden="true"></i>Duplicate</button></li>
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Downloaded"><i class="bi bi-download me-2" aria-hidden="true"></i>Download PDF</button></li>
                <li><hr class="dropdown-divider"></li>
                <li><button type="button" class="dropdown-item text-danger bdd-row-act" data-bdd-act="Voided"><i class="bi bi-trash3 me-2" aria-hidden="true"></i>Void</button></li>
              </ul>
            </div>
          </td>
        </tr>
        <tr>
          <td class="fw-semibold">INV-1043</td><td class="d-none d-sm-table-cell">Okapi Bikes</td><td class="text-end">$640</td>
          <td class="text-end">
            <div class="dropdown">
              <button type="button" class="btn btn-link link-secondary bdd-kebab" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Actions for INV-1043"><i class="bi bi-three-dots-vertical" aria-hidden="true"></i></button>
              <ul class="dropdown-menu dropdown-menu-end shadow-sm">
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Opened"><i class="bi bi-eye me-2" aria-hidden="true"></i>View</button></li>
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Duplicated"><i class="bi bi-copy me-2" aria-hidden="true"></i>Duplicate</button></li>
                <li><button type="button" class="dropdown-item bdd-row-act" data-bdd-act="Downloaded"><i class="bi bi-download me-2" aria-hidden="true"></i>Download PDF</button></li>
                <li><hr class="dropdown-divider"></li>
                <li><button type="button" class="dropdown-item text-danger bdd-row-act" data-bdd-act="Voided"><i class="bi bi-trash3 me-2" aria-hidden="true"></i>Void</button></li>
              </ul>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
  <p class="small text-body-secondary px-3 py-2 mb-0 border-top bdd-row-status" role="status">2 open invoices</p>
</div>

Notification center

  • data-bs-auto-close="outside"
  • badge
  • --bs-dropdown-min-width
  • visually-hidden

Click the toggle to open the menu.

A bell button with a counter badge opens a wide menu of notifications. The menu uses data-bs-auto-close="outside", so the Mark all as read button inside it updates the list and the badge without closing the panel; the badge text includes a visually-hidden label.

View code
<div class="dropdown bdd-notify">
  <button type="button" class="btn btn-light border position-relative bdd-bell" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">
    <i class="bi bi-bell" aria-hidden="true"></i><span class="visually-hidden">Notifications</span>
    <span class="position-absolute top-0 start-100 translate-middle badge rounded-pill bg-danger bdd-bell-count">3<span class="visually-hidden"> unread</span></span>
  </button>
  <div class="dropdown-menu dropdown-menu-end shadow p-0 bdd-notify-menu">
    <div class="d-flex align-items-center justify-content-between px-3 py-2 border-bottom">
      <span class="fw-semibold">Notifications</span>
      <button type="button" class="btn btn-link btn-sm text-decoration-none px-0 bdd-mark-read">Mark all as read</button>
    </div>
    <ul class="list-unstyled mb-0">
      <li><a class="dropdown-item d-flex gap-3 py-2 bdd-unread" href="#"><span class="bdd-ini rounded-circle bg-success-subtle text-success-emphasis" aria-hidden="true">JL</span><span class="text-wrap"><strong>Jonas Lee</strong> commented on Homepage hero<span class="d-block small text-body-secondary">4 minutes ago</span></span></a></li>
      <li><a class="dropdown-item d-flex gap-3 py-2 bdd-unread" href="#"><span class="bdd-ini rounded-circle bg-warning-subtle text-warning-emphasis" aria-hidden="true">AK</span><span class="text-wrap"><strong>Ama Kofi</strong> asked you to review Pricing v3<span class="d-block small text-body-secondary">1 hour ago</span></span></a></li>
      <li><a class="dropdown-item d-flex gap-3 py-2 bdd-unread" href="#"><span class="bdd-ini rounded-circle bg-info-subtle text-info-emphasis" aria-hidden="true"><i class="bi bi-cloud-check"></i></span><span class="text-wrap">Export of <strong>Q3 assets</strong> is ready<span class="d-block small text-body-secondary">Yesterday</span></span></a></li>
      <li><a class="dropdown-item d-flex gap-3 py-2" href="#"><span class="bdd-ini rounded-circle bg-secondary-subtle text-secondary-emphasis" aria-hidden="true">RT</span><span class="text-wrap"><strong>Rui Tanaka</strong> joined the workspace<span class="d-block small text-body-secondary">Monday</span></span></a></li>
    </ul>
    <a class="d-block text-center small py-2 border-top text-decoration-none" href="#">View all activity</a>
  </div>
</div>

Language and currency selector

  • .active
  • aria-current
  • btn-group
  • dropdown-item

Click the toggle to open the menu.

Two small dropdowns for a shop footer or header. A click listener moves .active and aria-current="true" to the chosen item and copies its label into the toggle, which Bootstrap does not do on its own; a check icon shows only on the active item.

View code
<div class="d-flex flex-wrap gap-2 align-items-center bdd-locale">
  <div class="dropdown">
    <button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"><i class="bi bi-globe2 me-2" aria-hidden="true"></i><span class="visually-hidden">Language: </span><span class="bdd-locale-label">English</span></button>
    <ul class="dropdown-menu shadow-sm">
      <li><button type="button" class="dropdown-item active" aria-current="true"><span class="bdd-locale-name">English</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">Deutsch</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">Espaรฑol</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">Franรงais</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">ๆ—ฅๆœฌ่ชž</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
    </ul>
  </div>
  <div class="dropdown">
    <button type="button" class="btn btn-outline-secondary dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"><span class="visually-hidden">Currency: </span><span class="bdd-locale-label">USD $</span></button>
    <ul class="dropdown-menu shadow-sm">
      <li><button type="button" class="dropdown-item active" aria-current="true"><span class="bdd-locale-name">USD $</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">EUR โ‚ฌ</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">GBP ยฃ</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
      <li><button type="button" class="dropdown-item"><span class="bdd-locale-name">JPY ยฅ</span><i class="bi bi-check2" aria-hidden="true"></i></button></li>
    </ul>
  </div>
</div>

Direction, alignment and options

Where the menu opens and how it lines up with its toggle: direction classes, split buttons, responsive alignment, the offset and reference options, and the four dropdown events in the order they fire.

Dropup, dropend, dropstart and centered

  • dropup
  • dropend
  • dropstart
  • dropdown-center

Open each toggle in turn.

The direction class goes on the wrapper, not the menu. Bootstrap turns it into a Popper placement and flips the caret; if a side has no room, as on a narrow phone, Popper flips or shifts the menu so it stays in view.

View code
<div class="bdd-dirs d-grid gap-3">
  <div class="dropup">
    <button type="button" class="btn btn-primary dropdown-toggle w-100 bdd-dir-up" data-bs-toggle="dropdown" aria-expanded="false">Dropup</button>
    <ul class="dropdown-menu"><li><a class="dropdown-item" href="#">Reply</a></li><li><a class="dropdown-item" href="#">Forward</a></li><li><a class="dropdown-item" href="#">Archive</a></li></ul>
  </div>
  <div class="dropend">
    <button type="button" class="btn btn-primary dropdown-toggle w-100 bdd-dir-end" data-bs-toggle="dropdown" aria-expanded="false">Dropend</button>
    <ul class="dropdown-menu"><li><a class="dropdown-item" href="#">Reply</a></li><li><a class="dropdown-item" href="#">Forward</a></li><li><a class="dropdown-item" href="#">Archive</a></li></ul>
  </div>
  <div class="dropstart">
    <button type="button" class="btn btn-primary dropdown-toggle w-100" data-bs-toggle="dropdown" aria-expanded="false">Dropstart</button>
    <ul class="dropdown-menu"><li><a class="dropdown-item" href="#">Reply</a></li><li><a class="dropdown-item" href="#">Forward</a></li><li><a class="dropdown-item" href="#">Archive</a></li></ul>
  </div>
  <div class="dropdown-center">
    <button type="button" class="btn btn-primary dropdown-toggle w-100" data-bs-toggle="dropdown" aria-expanded="false">Centered</button>
    <ul class="dropdown-menu"><li><a class="dropdown-item" href="#">Reply</a></li><li><a class="dropdown-item" href="#">Forward</a></li><li><a class="dropdown-item" href="#">Archive</a></li></ul>
  </div>
</div>

Split button: publish options

  • btn-group
  • dropdown-toggle-split
  • visually-hidden
  • --bs-btn-*

Open a menu and watch where it lands.

The main button publishes, the narrow split toggle opens the other choices. dropdown-toggle-split trims the padding around the caret, the visually-hidden span gives the caret a name, and --bs-btn-* variables recolor both halves to a deep teal without touching .btn-success.

View code
<div class="bdd-publish bg-body border rounded-3 p-3 shadow-sm">
  <p class="small text-body-secondary mb-1">Draft saved 2 minutes ago</p>
  <p class="fw-semibold mb-3">Winter catalog: launch page</p>
  <div class="btn-group">
    <button type="button" class="btn bdd-pub-btn">Publish now</button>
    <button type="button" class="btn bdd-pub-btn dropdown-toggle dropdown-toggle-split" data-bs-toggle="dropdown" aria-expanded="false"><span class="visually-hidden">More publish options</span></button>
    <ul class="dropdown-menu dropdown-menu-end shadow-sm">
      <li><a class="dropdown-item" href="#"><i class="bi bi-clock me-2" aria-hidden="true"></i>Schedule for later</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-eye me-2" aria-hidden="true"></i>Publish to staging</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-people me-2" aria-hidden="true"></i>Request review</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-floppy me-2" aria-hidden="true"></i>Save as template</a></li>
    </ul>
  </div>
</div>

Responsive alignment

  • dropdown-menu-md-end
  • data-bs-display="static"
  • flex-md-row

Open a menu and watch where it lands.

On phones the toggle stacks under the title on the left, from md up it moves to the right edge. dropdown-menu-md-end switches the menu from left to right alignment at the same breakpoint; responsive alignment needs data-bs-display="static" on the toggle, which turns off Popper positioning.

View code
<div class="bdd-team w-100 bg-body border rounded-3 shadow-sm">
  <div class="d-flex flex-column flex-md-row align-items-start align-items-md-center justify-content-between gap-2 p-3 border-bottom">
    <div>
      <h3 class="h6 mb-0">Team members</h3>
      <p class="small text-body-secondary mb-0">12 people, 3 pending invites</p>
    </div>
    <div class="dropdown">
      <button type="button" class="btn btn-outline-dark btn-sm dropdown-toggle bdd-team-btn" data-bs-toggle="dropdown" data-bs-display="static" aria-expanded="false"><i class="bi bi-funnel me-1" aria-hidden="true"></i>Filter by role</button>
      <ul class="dropdown-menu dropdown-menu-md-end shadow-sm">
        <li><a class="dropdown-item active" href="#" aria-current="true">All roles</a></li>
        <li><a class="dropdown-item" href="#">Owners</a></li>
        <li><a class="dropdown-item" href="#">Editors</a></li>
        <li><a class="dropdown-item" href="#">Viewers</a></li>
        <li><hr class="dropdown-divider"></li>
        <li><a class="dropdown-item" href="#">Pending invites</a></li>
      </ul>
    </div>
  </div>
  <ul class="list-unstyled mb-0 px-3 py-2 small">
    <li class="py-1">Priya Raman, Owner</li>
    <li class="py-1">Tomas Berg, Editor</li>
    <li class="py-1">Lena Hoff, Viewer</li>
  </ul>
</div>

Offset and reference: full-width picker

  • data-bs-offset
  • data-bs-reference="parent"
  • dropdown-item

Open a menu and watch where it lands.

The toggle is the small button on the right, but data-bs-reference="parent" makes Popper position the menu against the whole bar, and data-bs-offset="0,8" adds an 8px gap below it. A little CSS sets the menu to the bar width.

View code
<div class="bdd-ref-wrap w-100">
  <p class="small fw-semibold mb-2" id="bdd-ref-label">Saved search</p>
  <div class="dropdown bdd-ref d-flex align-items-center bg-body border rounded-3 shadow-sm ps-3">
    <i class="bi bi-search text-body-secondary me-2" aria-hidden="true"></i>
    <span class="flex-grow-1 text-truncate bdd-ref-value">Open orders over $500</span>
    <button type="button" class="btn bdd-ref-btn" data-bs-toggle="dropdown" data-bs-reference="parent" data-bs-offset="0,8" aria-expanded="false" aria-labelledby="bdd-ref-label"><i class="bi bi-chevron-down" aria-hidden="true"></i></button>
    <ul class="dropdown-menu shadow">
      <li><h6 class="dropdown-header">Saved searches</h6></li>
      <li><button type="button" class="dropdown-item active" aria-current="true">Open orders over $500</button></li>
      <li><button type="button" class="dropdown-item">Returns this week</button></li>
      <li><button type="button" class="dropdown-item">Customers without orders</button></li>
      <li><hr class="dropdown-divider"></li>
      <li><button type="button" class="dropdown-item text-primary"><i class="bi bi-plus-lg me-2" aria-hidden="true"></i>Save current filters</button></li>
    </ul>
  </div>
</div>

Dropdown events, logged live

  • show.bs.dropdown
  • shown.bs.dropdown
  • hide.bs.dropdown
  • clickEvent

Open the menu, then close it with a click outside or with Escape.

One listener per event on the .dropdown wrapper catches all four events, because they fire on the toggle and bubble up. The hide entries also say whether the event carried a clickEvent, which is how you tell an outside click from Escape or a hide() call.

View code
<div class="bdd-log d-grid gap-3 w-100">
  <div class="bg-body border rounded-3 p-3">
    <p class="small fw-semibold mb-2">Event log</p>
    <p class="small text-body-secondary mb-0 bdd-log-empty">No events yet.</p>
    <ol class="list-unstyled small font-monospace mb-0 bdd-log-list" aria-live="polite"></ol>
  </div>
  <div class="dropdown bdd-log-dd">
    <button type="button" class="btn btn-dark dropdown-toggle bdd-log-btn" data-bs-toggle="dropdown" aria-expanded="false">Sort: Newest</button>
    <ul class="dropdown-menu">
      <li><a class="dropdown-item" href="#">Newest</a></li>
      <li><a class="dropdown-item" href="#">Oldest</a></li>
      <li><a class="dropdown-item" href="#">Most replies</a></li>
    </ul>
  </div>
</div>

Forms, search and selection inside menus

Menus that hold inputs. They use data-bs-auto-close="outside" so typing, ticking and submitting never close the panel, plus the regular Bootstrap form classes.

Sign-in form in a dropdown

  • data-bs-auto-close="outside"
  • needs-validation
  • was-validated
  • px-4 py-3

Open the menu and press Sign in with empty fields.

The docs form pattern: a form with px-4 py-3 inside .dropdown-menu, a divider and two links below it. data-bs-auto-close="outside" keeps the panel open while the reader clicks into fields or the submit button, and the Bootstrap validation classes show the errors in place.

View code
<div class="dropdown bdd-signin">
  <button type="button" class="btn btn-primary dropdown-toggle bdd-signin-btn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false"><i class="bi bi-person-circle me-2" aria-hidden="true"></i>Sign in</button>
  <div class="dropdown-menu shadow bdd-signin-menu">
    <form class="px-4 py-3 bdd-signin-form" novalidate>
      <div class="mb-3">
        <label for="bdd-signin-email" class="form-label">Email</label>
        <input type="email" class="form-control" id="bdd-signin-email" placeholder="you@example.com" autocomplete="email" required>
        <div class="invalid-feedback">Enter the email you signed up with.</div>
      </div>
      <div class="mb-3">
        <label for="bdd-signin-pass" class="form-label">Password</label>
        <input type="password" class="form-control" id="bdd-signin-pass" autocomplete="current-password" minlength="8" required>
        <div class="invalid-feedback">At least 8 characters.</div>
      </div>
      <div class="form-check mb-3">
        <input class="form-check-input" type="checkbox" id="bdd-signin-keep">
        <label class="form-check-label" for="bdd-signin-keep">Keep me signed in</label>
      </div>
      <button type="submit" class="btn btn-primary w-100 bdd-signin-submit">Sign in</button>
      <p class="small text-success mt-2 mb-0 d-none bdd-signin-ok" role="status">Signed in. Welcome back.</p>
    </form>
    <div class="dropdown-divider"></div>
    <a class="dropdown-item" href="#">New here? Create an account</a>
    <a class="dropdown-item" href="#">Forgot password?</a>
  </div>
</div>

Searchable time zone picker

  • shown.bs.dropdown
  • form-control-sm
  • d-none
  • dropdown-item

Open the menu and type a city name.

A search field at the top of the menu filters the items as you type by toggling d-none on each list item, and a hidden "No matches" line appears when nothing is left. The shown.bs.dropdown listener moves focus into the field, and choosing an item writes it to the toggle.

View code
<div class="bdd-tz w-100">
  <p class="small fw-semibold mb-2" id="bdd-tz-label">Meeting time zone</p>
  <div class="dropdown">
    <button type="button" class="btn btn-light border w-100 d-flex align-items-center justify-content-between bdd-tz-btn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false" aria-describedby="bdd-tz-label"><span class="bdd-tz-value">Lisbon (UTC+0)</span><i class="bi bi-chevron-expand" aria-hidden="true"></i></button>
    <div class="dropdown-menu w-100 shadow pt-0 bdd-tz-menu">
      <div class="p-2 border-bottom">
        <label for="bdd-tz-search" class="visually-hidden">Search time zones</label>
        <input type="search" class="form-control form-control-sm bdd-tz-search" id="bdd-tz-search" placeholder="Search cities" autocomplete="off">
      </div>
      <ul class="list-unstyled mb-0 bdd-tz-list">
        <li><button type="button" class="dropdown-item">Honolulu (UTC-10)</button></li>
        <li><button type="button" class="dropdown-item">Los Angeles (UTC-8)</button></li>
        <li><button type="button" class="dropdown-item">New York (UTC-5)</button></li>
        <li><button type="button" class="dropdown-item">Sรฃo Paulo (UTC-3)</button></li>
        <li><button type="button" class="dropdown-item active" aria-current="true">Lisbon (UTC+0)</button></li>
        <li><button type="button" class="dropdown-item">Berlin (UTC+1)</button></li>
        <li><button type="button" class="dropdown-item">Nairobi (UTC+3)</button></li>
        <li><button type="button" class="dropdown-item">Bengaluru (UTC+5:30)</button></li>
        <li><button type="button" class="dropdown-item">Singapore (UTC+8)</button></li>
        <li><button type="button" class="dropdown-item">Auckland (UTC+12)</button></li>
      </ul>
      <p class="dropdown-item-text small text-body-secondary mb-0 d-none bdd-tz-empty">No matches. Try another city.</p>
    </div>
  </div>
</div>

Multi-select checklist with count

  • form-check-input
  • data-bs-auto-close="outside"
  • badge
  • dropdown-item

Open the menu and tick a few tags.

Each row is a label styled as a dropdown-item that wraps a checkbox, so the whole row is clickable and Tab moves through the checkboxes. The menu stays open between ticks, and a change listener updates the count badge on the toggle; Clear unticks everything.

View code
<div class="dropdown bdd-tags">
  <button type="button" class="btn btn-light border dropdown-toggle d-inline-flex align-items-center gap-2 bdd-tags-btn" data-bs-toggle="dropdown" data-bs-auto-close="outside" aria-expanded="false">Project tags <span class="badge rounded-pill text-bg-primary bdd-tags-count">1</span><span class="visually-hidden"> selected</span></button>
  <div class="dropdown-menu shadow-sm bdd-tags-menu">
    <h6 class="dropdown-header">Show projects tagged</h6>
    <label class="dropdown-item d-flex gap-2 align-items-center"><input class="form-check-input m-0 bdd-tag" type="checkbox" value="branding" checked>Branding</label>
    <label class="dropdown-item d-flex gap-2 align-items-center"><input class="form-check-input m-0 bdd-tag" type="checkbox" value="web">Web design</label>
    <label class="dropdown-item d-flex gap-2 align-items-center"><input class="form-check-input m-0 bdd-tag" type="checkbox" value="print">Print</label>
    <label class="dropdown-item d-flex gap-2 align-items-center"><input class="form-check-input m-0 bdd-tag" type="checkbox" value="motion">Motion</label>
    <label class="dropdown-item d-flex gap-2 align-items-center"><input class="form-check-input m-0 bdd-tag" type="checkbox" value="packaging">Packaging</label>
    <div class="dropdown-divider"></div>
    <div class="d-flex justify-content-between px-3">
      <button type="button" class="btn btn-link btn-sm px-0 text-decoration-none bdd-tags-clear">Clear</button>
      <button type="button" class="btn btn-primary btn-sm bdd-tags-done">Done</button>
    </div>
  </div>
</div>

Dark, themed and navbar menus

Color modes, the --bs-dropdown-* variables and custom menu layouts. These show how far one dropdown component stretches before you need anything but Bootstrap.

Dark editor menu bar with shortcuts

  • data-bs-theme="dark"
  • kbd
  • btn-group
  • dropdown-item

Click the toggle to open the menu.

A dark toolbar on a light page: data-bs-theme="dark" on the toolbar wrapper turns the buttons and every menu inside it dark, which replaces the .dropdown-menu-dark class deprecated in 5.3.0. Each item has an icon and a keyboard hint in a kbd element pushed to the right with ms-auto.

View code
<div class="bdd-editor w-100 rounded-3 overflow-visible shadow-sm">
  <div class="d-flex flex-wrap gap-1 align-items-center bg-body-tertiary text-body px-2 py-1 rounded-top-3 bdd-editor-bar" data-bs-theme="dark">
    <div class="dropdown">
      <button type="button" class="btn btn-sm bdd-editor-btn bdd-file-btn" data-bs-toggle="dropdown" aria-expanded="false">File</button>
      <ul class="dropdown-menu shadow bdd-editor-menu">
        <li><button type="button" class="dropdown-item"><i class="bi bi-file-earmark-plus" aria-hidden="true"></i>New file<kbd>Ctrl N</kbd></button></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-folder2-open" aria-hidden="true"></i>Open<kbd>Ctrl O</kbd></button></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-floppy" aria-hidden="true"></i>Save<kbd>Ctrl S</kbd></button></li>
        <li><hr class="dropdown-divider"></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-printer" aria-hidden="true"></i>Print<kbd>Ctrl P</kbd></button></li>
        <li><button type="button" class="dropdown-item" disabled><i class="bi bi-cloud-upload" aria-hidden="true"></i>Sync<kbd>Offline</kbd></button></li>
      </ul>
    </div>
    <div class="dropdown">
      <button type="button" class="btn btn-sm bdd-editor-btn" data-bs-toggle="dropdown" aria-expanded="false">Edit</button>
      <ul class="dropdown-menu shadow bdd-editor-menu">
        <li><button type="button" class="dropdown-item"><i class="bi bi-arrow-counterclockwise" aria-hidden="true"></i>Undo<kbd>Ctrl Z</kbd></button></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-arrow-clockwise" aria-hidden="true"></i>Redo<kbd>Ctrl Y</kbd></button></li>
        <li><hr class="dropdown-divider"></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-search" aria-hidden="true"></i>Find<kbd>Ctrl F</kbd></button></li>
      </ul>
    </div>
    <div class="dropdown">
      <button type="button" class="btn btn-sm bdd-editor-btn" data-bs-toggle="dropdown" aria-expanded="false">View</button>
      <ul class="dropdown-menu shadow bdd-editor-menu">
        <li><button type="button" class="dropdown-item"><i class="bi bi-layout-sidebar" aria-hidden="true"></i>Sidebar<kbd>Ctrl B</kbd></button></li>
        <li><button type="button" class="dropdown-item"><i class="bi bi-zoom-in" aria-hidden="true"></i>Zoom in<kbd>Ctrl +</kbd></button></li>
      </ul>
    </div>
    <span class="ms-auto small text-body-secondary px-2">notes.md</span>
  </div>
  <div class="bg-body p-3 rounded-bottom-3 border border-top-0 font-monospace small text-body-secondary bdd-editor-doc">
    <p class="mb-1"># Launch checklist</p>
    <p class="mb-1">- Final copy review</p>
    <p class="mb-0">- Swap hero photo</p>
  </div>
</div>

Menu themed with --bs-dropdown-* variables

  • --bs-dropdown-bg
  • --bs-dropdown-link-active-bg
  • --bs-dropdown-border-radius
  • --bs-dropdown-item-padding-y

Click the toggle to open the menu.

A cookbook "save to collection" menu restyled only through the --bs-dropdown-* custom properties on one prefixed class: cream background, terracotta active item, rounder corners, roomier items and a softer divider. The toggle uses the matching --bs-btn-* variables.

View code
<div class="bdd-recipe bg-body border rounded-4 p-3 shadow-sm">
  <p class="small text-body-secondary mb-1">Dinner, 35 min</p>
  <h3 class="h5 mb-3">Roasted squash and farro bowl</h3>
  <div class="dropdown">
    <button type="button" class="btn bdd-recipe-btn dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false"><i class="bi bi-bookmark-heart me-2" aria-hidden="true"></i>Save to collection</button>
    <ul class="dropdown-menu bdd-recipe-menu">
      <li><h6 class="dropdown-header">Your collections</h6></li>
      <li><a class="dropdown-item active" href="#" aria-current="true"><i class="bi bi-check2-circle me-2" aria-hidden="true"></i>Weeknight dinners</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-circle me-2" aria-hidden="true"></i>Meal prep</a></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-circle me-2" aria-hidden="true"></i>Autumn favorites</a></li>
      <li><hr class="dropdown-divider"></li>
      <li><a class="dropdown-item" href="#"><i class="bi bi-plus-lg me-2" aria-hidden="true"></i>New collection</a></li>
    </ul>
  </div>
</div>

App launcher grid

  • dropdown-menu-end
  • CSS grid
  • dropdown-item
  • aria-label

Click the toggle to open the menu.

An icon-only grid button opens a menu laid out as a three-column grid of app tiles. The tiles are still .dropdown-item links, so the arrow keys move through them and Escape closes the menu; only the layout and tile styling are custom.

View code
<div class="bdd-apps-bar w-100 d-flex align-items-center justify-content-between bg-body border rounded-3 px-3 py-2 shadow-sm">
  <span class="fw-semibold">Harborline</span>
  <div class="dropdown">
    <button type="button" class="btn btn-light bdd-apps-btn" data-bs-toggle="dropdown" aria-expanded="false" aria-label="Open apps"><i class="bi bi-grid-3x3-gap-fill" aria-hidden="true"></i></button>
    <div class="dropdown-menu dropdown-menu-end shadow p-2 bdd-apps">
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-primary-subtle text-primary-emphasis" aria-hidden="true"><i class="bi bi-envelope"></i></span>Mail</a>
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-success-subtle text-success-emphasis" aria-hidden="true"><i class="bi bi-calendar3"></i></span>Calendar</a>
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-warning-subtle text-warning-emphasis" aria-hidden="true"><i class="bi bi-kanban"></i></span>Boards</a>
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-info-subtle text-info-emphasis" aria-hidden="true"><i class="bi bi-chat-dots"></i></span>Chat</a>
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-danger-subtle text-danger-emphasis" aria-hidden="true"><i class="bi bi-images"></i></span>Photos</a>
      <a class="dropdown-item bdd-app" href="#"><span class="bdd-app-ico bg-secondary-subtle text-secondary-emphasis" aria-hidden="true"><i class="bi bi-cloud"></i></span>Drive</a>
    </div>
  </div>
</div>

What is a Bootstrap dropdown?

Click opens it. Hover never does, and the Bootstrap team calls that an intentional design decision.

Behind the click sits Bootstrap’s JavaScript plugin, with Popper handling position. The list of links or actions only appears because the plugin toggles it.

CSS-only dropdown menus need no script at all, which this component can’t say. The plugin does the toggling, closing and positioning, and Bootstrap adds no ARIA menu roles to the markup.

Required classes and elements

The wrapper is .dropdown, or any element that declares position: relative. A .btn-group works too.

The toggle needs .dropdown-toggle plus data-bs-toggle=”dropdown”. A button is the recommended element. A link works as well, and the docs suggest adding role=”button” to it.

The menu is .dropdown-menu, usually a ul, and each item is a .dropdown-item on an a or button element, one per li.

The plugin opens a menu by toggling the .show class on .dropdown-menu.

Any of the Bootstrap button styles can act as the toggle once .dropdown-toggle is added, in every size.

Menu content: items, headers, dividers and text

Items can be a elements or button elements, whichever matches the action. Around them you can add:

  • .dropdown-header on an h6 to label a group of items
  • .dropdown-divider on an hr between groups
  • .dropdown-item-text for non-interactive text
  • .active on the current item, and .disabled to grey one out

Pair .active with aria-current so assistive technology announces the state. Use page for the current page and true for the current item in a set.

The Sass default for menu width is a minimum of 10rem, and the docs advise extra sizing styles when a menu holds free-form text.

How to add a Bootstrap dropdown to a page

Dropdowns require Popper, and bootstrap.bundle.min.js already includes it. So the bundle is the only script you need, placed just before the closing body tag.

  1. Add the bootstrap.min.css link from jsDelivr to the head (version 5.3.8 as of October 2026).
  2. Wrap the toggle and the menu in a div with the class dropdown.
  3. Add a button with the classes btn btn-secondary dropdown-toggle, plus type=”button”, data-bs-toggle=”dropdown” and aria-expanded=”false”.
  4. Add a ul with the class dropdown-menu, then one li per item with an a that carries dropdown-item.
  5. Place the script tag for bootstrap.bundle.min.js just before the closing body tag.
  6. Open the page and click the toggle. The menu shows, and a click outside or the Esc key closes it.

Because the markup is ordinary HTML, any template language or CMS can output it.

The bundle is one file with Popper inside, and it’s the default in the docs quick start. If you’d rather load separate files, popper.min.js goes first (@popperjs/core 2.11.8 in the current docs), then bootstrap.min.js.

Skip Popper and the plugin throws a TypeError (“Bootstrap’s dropdowns require Popper”) when the menu first opens, per the dropdown.js source.

No jQuery is involved. The 5.3.8 CDN instructions list Popper and Bootstrap’s script only.

Projects with a build step can install from npm instead (npm install bootstrap@5.3.8, the current release in October 2026).

Direction and alignment options for the dropdown menu

A class on the parent sets direction, and a class on the menu sets alignment. With neither, the menu opens below the toggle and lines up with its left edge.

For direction, .dropup opens the menu above the toggle, .dropend opens it to the right and .dropstart to the left. There are also .dropdown-center and .dropup-center, which center the menu below or above. In RTL layouts the sides mirror, so .dropstart appears on the right.

Positioning comes from Popper, which reads the available viewport and flips the menu when the preferred side has no room.

ClassResultExtra requirement
.dropdown-menu-endAligns the menu to the right edge of the toggleNone
.dropdown-menu-lg-endLeft-aligned by default, right-aligned from the lg breakpointdata-bs-display=”static” on the toggle
.dropdown-menu-end with .dropdown-menu-lg-startRight-aligned by default, left-aligned from lgdata-bs-display=”static” on the toggle

Swap lg for sm, md, xl or xxl to move the switch point. The docs require static display first, because Popper otherwise controls placement.

Inside a navbar the attribute is unnecessary, since Popper is not used there.

Breakpoint variants fit a responsive layout where the toggle sits at the right edge on phones but mid-row on desktop.

Bootstrap dropdown options, methods and events

Every option can be set from markup or from script. Beyond the options, the plugin exposes 7 methods and fires 4 events.

Data attributes

Add data-bs-toggle=”dropdown” to a link or button and the plugin takes over.

Keep the attribute even when you initialize the dropdown from script. Bootstrap relies on it to close open menus at the application level.

Options follow the pattern data-bs- plus the option name in kebab-case, so autoClose becomes data-bs-auto-close and offset becomes data-bs-offset=”10,20″.

Since 5.2.0 there is also an experimental data-bs-config attribute that takes options as a JSON string, and separate data-bs-* attributes override it.

JavaScript API

Call new bootstrap.Dropdown(element) on each toggle, or pass a selector string, and add an options object as the second argument.

The show, hide and toggle methods open, close or flip the menu. update recalculates its position and dispose removes the stored instance data. getInstance and getOrCreateInstance return the instance for an element.

Use plain JavaScript when an option needs a value that attributes cannot carry, like an element for boundary, a function for popperConfig, or an object with getBoundingClientRect for reference.

React, Vue and Angular are the exception. Bootstrap’s docs say its JavaScript is not fully compatible with frameworks that assume full control of the DOM, and point to React Bootstrap, ng-bootstrap and ngx-bootstrap instead.

Options and defaults

Each option has a documented default.

OptionDefaultAccepted values
autoClosetruetrue, false, ‘inside’, ‘outside’
boundary‘clippingParents’string, or an element (JavaScript only)
display‘dynamic’‘dynamic’, or ‘static’ to turn Popper off
offset[0, 2]array, string (“10,20” in attributes) or function
popperConfignullobject, or function that receives Bootstrap’s default config
reference‘toggle’‘toggle’, ‘parent’, an element, or an object with getBoundingClientRect

autoClose is the one people trip over. With true, any click closes the menu, inside or outside. With false it closes only through the toggle or a hide or toggle call. ‘inside’ closes it only on clicks inside the menu, and ‘outside’ only on clicks outside.

For a menu that holds form fields, set data-bs-auto-close=”outside”, as the docs form example does. The close handler in the 5.3 source also ignores events from input, select, option, textarea and form elements inside the menu.

The docs contradict themselves on one point. The description of false says Esc will not close the menu, while the note in the same table cell says Esc always does. The keydown handler in the 5.3.8 source hides an open menu on Esc whatever autoClose is set to, as long as focus is on the toggle or inside the menu, so the note is the accurate one.

Events

All four events fire on the toggle and then bubble, so one listener on the .dropdown parent covers every dropdown inside it.

show.bs.dropdown and hide.bs.dropdown fire as soon as the show or hide method is called. shown.bs.dropdown and hidden.bs.dropdown wait until the menu is visible or hidden and the CSS transitions have finished.

Methods return before the transition ends, so wait for shown or hidden before reading the menu state. The hide and hidden events also carry a clickEvent property when a click triggered them.

Does the Bootstrap dropdown support keyboard navigation and screen readers?

Partly. The plugin handles keyboard movement and closing, but it adds no ARIA menu roles, so screen reader semantics are left to the author.

Arrow keys move through the .dropdown-item elements and Esc closes the menu. Tab moves focus inside an open menu without closing it (dropdown.js source).

Everything else is on you. That means role=”button” on a link that works as the toggle, aria-current on the active item, and role and aria- attributes if the menu must be a true ARIA menu.

The reason is scope. The ARIA menu role is meant for application-like menus that trigger actions, and it allows only menu items, checkbox items, radio items, radio groups and sub-menus.

A dropdown that holds a login form or a search field cannot qualify. That is why Bootstrap keeps the markup generic.

Older Bootstrap 3 tutorials, W3Schools among them, put role=”menu” on the list. That is valid only when every child is a real menu item and the menu follows the full menu keyboard model.

The W3C’s ARIA Authoring Practices Guide describes that model as the menu button pattern. The toggle gets aria-haspopup (aria-controls is optional), aria-expanded switches between true and false, and Enter or Space opens the menu with focus on the first item.

Bootstrap’s toggle ships with aria-expanded=”false” in the markup, and the plugin keeps the value in sync as the menu opens and closes.

Run a keyboard-only pass and a screen reader pass before release, as part of a web accessibility checklist.

Common Bootstrap dropdown patterns: navbar, split button, form and dark menu

Navbar items, split buttons, form panels and themed menus cover most real projects. Each one changes the markup around .dropdown-menu and leaves the plugin itself alone.

Navbar dropdown

A navbar dropdown keeps the wrapper and the toggle on separate, nested elements. The docs say menus need a wrapping element for positioning, so .nav-item and .nav-link stay separate.

The item is an li with the classes nav-item dropdown. Inside it, the toggle is an a with nav-link dropdown-toggle, role=”button”, data-bs-toggle=”dropdown” and aria-expanded=”false”. The menu is a ul with dropdown-menu, placed in the same li.

Placement works differently here. Bootstrap marks navbar menus with data-bs-popper=”static”, and the compiled Sass switches .dropdown-menu to position: absolute only from the expand breakpoint up, so below that breakpoint the menu sits in the flow of the collapsed panel.

Collapse breakpoints and togglers come from the Bootstrap navbar component, which has its own set of classes.

One limit carries over from Bootstrap’s design. Mark Otto, one of its creators, noted in a 2012 post that a click opens the menu, so the toggle cannot also navigate to a page of its own.

Split button dropdown

The split toggle trims its horizontal padding by 25% and drops the left margin, per the Bootstrap docs. That keeps the caret centered in a smaller hit area.

The markup is a .btn-group holding two buttons, then the menu. The second button carries dropdown-toggle, dropdown-toggle-split and data-bs-toggle=”dropdown”.

Give that button a visually-hidden span reading Toggle Dropdown, because a caret alone gives a screen reader nothing to announce.

A split dropstart is the odd one out. The docs put the toggle and the menu before the main button in the source order, so the menu opens on the left of the main button.

Form inside a dropdown

There are two ways to do it. A form with px-4 py-3 can sit inside .dropdown-menu, with a divider and extra links below it, which is the usual sign-in panel. Or the form itself can carry .dropdown-menu and p-4, which suits a single compact form.

Field styling comes from the regular Bootstrap form classes (form-label, form-control, form-check), so nothing dropdown-specific is needed.

Spacing is the catch. Horizontal menu padding defaults to 0 ($dropdown-padding-x), so a form without px-4 or p-4 touches the menu edges.

Dark menu and styling

Dark menus changed in v5.3.0. The migration guide deprecates .dropdown-menu-dark and replaces it with data-bs-theme=”dark”.

Where the attribute sits decides how far it reaches. On the html element, every component turns dark. On a wrapper, everything inside it does. On the .dropdown itself, only that menu does.

The same attribute replaces .navbar-dark, so a dark navbar and the menus inside it follow one switch.

Since v5.2.0 the menu reads 26 local CSS variables on .dropdown-menu, all prefixed –bs-dropdown-. Bootstrap’s own blue theme example overrides –bs-dropdown-bg and –bs-dropdown-link-active-bg inside a data-bs-theme=”blue” selector. If you work in Sass, variable overrides go after the functions import and before the variables import, per the 5.2.0 migration notes.

One trade-off sits in the color modes docs. Switching the color mode type to a media query makes themes automatic but removes per-component theming.

Can a Bootstrap dropdown open on hover or hold nested menus?

Neither is built in. The docs state that dropdowns toggle on click rather than hover, and the 5.3 dropdown page describes no submenu pattern.

Otto’s 2012 design post gives the history. Before Bootstrap was open sourced the dropdowns fired on hover, and the team switched to click because the menu disappeared the moment the cursor left it.

His rule was simple. Hover indicates, click acts, and opening a dropdown is an explicit action.

A hover rule fails on touch screens, which have no hover. It also leaves aria-expanded at false, since a CSS rule never runs the plugin, and any gap between toggle and menu closes the menu as the pointer crosses it.

Bootstrap leaves a small gap on purpose: the $dropdown-spacer Sass variable is .125rem. Drupal’s bootstrap_barrio theme stylesheet deals with it directly, setting margin-left to 0 on flyout menus so the pointer never crosses a dead zone, and it applies its hover rule only from 768px up.

Otto’s reason and the barrio fix describe the same failure from two sides.

A nested menu is a second .dropdown-menu inside an item, positioned with top: 0 and left: 100% in the barrio stylesheet, plus extra CSS or script to show and hide it.

Most implementations write that logic by hand, and examples of JavaScript menus show the usual approaches.

My advice is to keep top-level toggles click-only and stop at one nested level. If the design really demands hover, add it only from the md breakpoint up. Bootstrap Studio’s multilevel guide also advises regular dropdowns where possible, citing better usability on mobile devices.

Bootstrap 4 versus Bootstrap 5 dropdown differences

Bootstrap 5 namespaced every plugin data attribute, so a toggle that still carries data-toggle gets no behavior. Copy-pasted v4 markup fails quietly rather than loudly.

AspectBootstrap 4Bootstrap 5
Toggle attributedata-toggle=”dropdown”data-bs-toggle=”dropdown”
ScriptsjQuery plus Popper.js 1.xPopper 2.x, no jQuery
Side openings.dropleft, .dropright.dropstart, .dropend
Right alignment.dropdown-menu-right.dropdown-menu-end
Item markupdiv with linksul and li supported
Auto closeNot availableautoClose option
Event targetParent .dropdownToggle button, then bubbles up

The v4 flip option no longer exists. Flipping is plain Popper configuration now, and an empty fallbackPlacements array turns it off, per the migration guide.

The browser floor moved too. Projects that must still run in Internet Explorer 11 hit a cross-browser compatibility wall, because Bootstrap 5 dropped IE 10 and 11 along with Legacy Edge.

Bootstrap 4 has been end of life since January 1, 2023, according to the release schedule in Bootstrap’s twbs/release repository. Its final release, 4.6.2, shipped on July 19, 2022. Bootstrap 5 has been the default version since May 5, 2021, and 5.3.x is the current line as of October 2026.

Bootstrap 6 exists only as a pre-release, v6.0.0-alpha.1, published on October 8, 2026 and tagged next on npm. The alpha.1 notes list renaming the dropdown to menu, and the 6.0 docs create it with new bootstrap.Menu(menuToggleEl) for each element matched by [data-bs-toggle=”menu”].

Vendors are acting on the v4 end of life. DevExpress Blazor removed its Bootstrap v4-based theme stylesheets in release v26.1, following a March 2026 announcement.

Pick 5.3.x for anything shipping today. Treat the v6 alpha as a preview of the rename, not a target.

Why is a Bootstrap dropdown not working or cut off?

Most reports come down to a dead click, a misplaced menu, an unexpected flip upward or a clipped menu. Each has its own cause, and the clipping case has the least obvious fix.

SymptomCauseFix
Click does nothingScript missing, Popper missing, or data-toggle used on a v5 pageLoad bootstrap.bundle.min.js before the closing body tag and use data-bs-toggle
Menu appears far from the toggleWrapper does not declare position: relativeWrap toggle and menu in .dropdown
Menu opens upwardPopper flips it when space below runs outLeave it, or empty fallbackPlacements in popperConfig
Menu is cut offAncestor with overflow hidden, auto or scrollSet Popper’s strategy to fixed through popperConfig

An absolutely positioned menu cannot escape an ancestor that clips overflow. Bootstrap’s issue tracker records the pattern in #24251, which covers large dropdowns becoming unusable inside an overflow scroll container, and responsive wrappers such as Bootstrap tables with .table-responsive are the usual host.

The fix is a popperConfig function that spreads Bootstrap’s default config and sets strategy to “fixed”.

Koha, the open source library system, patched exactly this in Bug 40857 (September 2025). A combobox menu inside a Bootstrap modal scrolled with the modal body, so the patch passes a fixed strategy for modal contexts.

Two Bootstrap sources look like they disagree on the syntax. A merged docs pull request (#42470) sets data-bs-strategy=”fixed” on toggles in the live previews of resizable examples to stop menus clipping, but it fixes the v6 docs, where the Menu component lists a strategy option. The 5.3 options table lists no strategy option.

On 5.3.x, use popperConfig.

Bootstrap dropdown FAQ

How do I show the selected item’s text on the toggle button?

Bootstrap has no built-in select behavior, so a click listener does the job. Copy the clicked .dropdown-item text into the toggle, then move .active and aria-current=”true” to that item so assistive technology hears the choice.

Can a dropdown toggle be disabled?

Yes. Add the disabled attribute to a button toggle, and the docs say Bootstrap applies pointer-events: none to it. A link toggle has no such attribute, so it needs .disabled, aria-disabled=”true” and tabindex=”-1″ to keep keyboard users out.

Why does a dropdown menu appear behind a fixed navbar or modal?

Stacking order decides it. Bootstrap’s z-index scale gives menus 1000, below sticky at 1020, fixed at 1030 and modal at 1055, so a menu that overlaps one of those layers from outside it renders underneath.

Changing $zindex-dropdown alone is risky, because the docs say that altering one value likely means altering them all.

Which setting controls dropdown menu width?

Set the –bs-dropdown-min-width variable on the .dropdown-menu, or change the $dropdown-min-width Sass variable to affect every menu. A menu holding free text also needs a max-width style, as the docs example shows.

Verifying Every Bootstrap Dropdown After an Upgrade

After an upgrade, click each toggle to open it, then close it with Esc and with an outside click. Look at alignment and clipping at the narrowest and widest breakpoints. Last, try the arrow keys, Tab and aria-expanded.

That order follows dependency. A dead toggle makes every later check meaningless, and keyboard behavior cannot be judged until the menu opens reliably.

The downside is manual effort, because each variant (navbar, split button, form, themed menu) needs its own pass.

As of October 2026 this routine targets the 5.3 line, and a stable Bootstrap 6 release would reset it.

The same routine suits other Bootstrap components that depend on Bootstrap’s JavaScript.