--- /dev/null
+---
+title: Migration
+description: Track and review changes to the Bootstrap source files, documentation, and components to help you migrate from v5 to v6.
+aliases:
+ - "/migration/"
+ - "/docs/[[config:docs_version]]/migration/"
+toc: true
+---
+
+## Upgrade
+
+Bootstrap 6 is a major release with many breaking changes to modernize our codebase, adopt newer build tools, and improve customization. Keep reading for a guide on how to migrate from v5 to v6, and a full changelog of what's new.
+
+1. Bump your Bootstrap dependency:
+
+ ```json
+ {
+ "dependencies": {
+ "bootstrap": "^6.0.0"
+ }
+ }
+ ```
+
+2. If using all of Bootstrap's Sass files, include it in your Sass using `@use`:
+
+ ```scss
+ @use "bootstrap/scss/bootstrap";
+ ```
+
+ With this, you can then easily override Bootstrap's Sass variables and maps:
+
+ ```scss
+ @use "bootstrap/scss/bootstrap" with (
+ $spacer: 1rem,
+ $enable-reduced-motion: true,
+ );
+ ```
+
+3. If using only certain parts of Bootstrap's Sass files, you can use `@use` to import them individually. Be aware that our Sass file structure has changed and you may need to adjust your imports accordingly.
+
+ ```scss
+ @use "bootstrap/scss/forms";
+ ```
+
+4. Update HTML and CSS per the changelog and updates in the documentation.
+
+5. Recompile your Sass to see the changes.
+
+## Changelog
+
+### CSS
+
+- **Implemented CSS layers** in `_root.scss` and applied them to all our Sass files.
+ - Layers are set in `_root.scss` and then utilized across separate Sass partials.
+ - We cannot, unfortunately, wrap `@use` or `@forward` statements in `@layer`—Sass expects those to be top level at all times. Also, while CSS allows `@import "file.css" layer(name)`, Sass also does not support that.
+- Clarified and simplified CSS-Sass setup.
+- New, streamlined color modes and theming.
+ - Removed `_maps.scss`
+ - Removed `_variables-dark.scss`
+ - Added `_colors.scss`, splitting colors out to their own file
+ - Removed `_variables.scss`, consolidating all variables into `_config.scss`
+ - Added `_theme.scss` where we setup all our global theming for how colors are applied
+- **Updated lg, xl, and 2xl breakpoints and containers.**
+ - Increased the `lg` breakpoint from 992px to 1024px; it's container remains the same at 960px.
+ - Increased the `xl` breakpoint from 1200px to 1280px, and it's container from 1140px to 1200px.
+ - Renamed `xxl` to `2xl` for better scaling with additional custom breakpoints
+ - Increased the `2xl` breakpoint from 1400px to 1536px, and it's container from 1320px to 1440px.
+- **Adopted modern CSS color functions.** All Sass color variables now use `oklch()` notation (e.g., `$blue: oklch(60% 0.24 240)`) and tint/shade scales are generated with `color-mix(in lab, ...)` in the compiled CSS. The v5 `$*-rgb` CSS custom properties and `rgba()` patterns have been removed. This requires browser support for `color-mix()` and `oklch()`.
+- **New theme token system with `.theme-*` classes.** Per-component color variant classes (like `.alert-primary`, `.badge.bg-primary`, `.btn-primary`) are replaced by a composable `.theme-{name}` pattern. Adding `.theme-primary` to a component sets `--theme-bg`, `--theme-text`, `--theme-border`, `--theme-contrast`, and other semantic CSS custom properties that the component reads. This applies across buttons, badges, alerts, cards, accordions, and more.
+- **Responsive classes now use a breakpoint prefix instead of an infix.** Class names follow the Tailwind-style `breakpoint:class` pattern (e.g., `md:d-none` instead of `d-md-none`). In HTML, use the unescaped colon: `class="md:d-none"`. This applies to utilities, grid, and all responsive components.
+
+<BsTable>
+| Category | Before (v5) | After (v6) |
+|---|---|---|
+| Utilities | `.d-md-none`, `.p-lg-3` | `.md:d-none`, `.lg:p-3` |
+| Grid columns | `.col-md-6` | `.md:col-6` |
+| Row columns | `.row-cols-md-3` | `.md:row-cols-3` |
+| Offsets | `.offset-md-2` | `.md:offset-2` |
+| Gutters | `.g-md-3`, `.gx-md-3` | `.md:g-3`, `.md:gx-3` |
+| CSS Grid | `.g-col-md-4` | `.md:g-col-4` |
+| Containers | `.container-sm` | `.sm:container` |
+| Navbar | `.navbar-expand-md` | `.md:navbar-expand` |
+| Drawer | `.offcanvas-md` | `.md:drawer` |
+| Tables | `.table-responsive-md` | `.md:table-responsive` |
+| List group | `.list-group-horizontal-md` | `.md:list-group-horizontal` |
+| Sticky | `.sticky-md-top` | `.md:sticky-top` |
+| Stacks | `.vstack-md` | `.md:vstack` |
+| Stepper | `.stepper-horizontal-md` | `.md:stepper-horizontal` |
+| Dialog | `.dialog-fullscreen-sm-down` | `.sm-down:dialog-fullscreen` |
+| Print | `.d-print-none` | `.print:d-none` |
+</BsTable>
+
+### Sass
+
+- Dropped support for Node Sass, including no longer testing any of our source CSS against it.
+ - Rearranged several Sass files in the process.
+- Removed `add()` and `subtract()` functions. Use `calc()` instead.
+- Removed `create-css-vars()` mixin (unused).
+- **Renamed `breakpoint-infix()` to `breakpoint-prefix()`.** The function now returns a prefix string (e.g., `"md\:"`) instead of an infix (e.g., `"-md"`). The `loop-breakpoints-up` and `loop-breakpoints-down` mixins now expose `$prefix` instead of `$infix`. Update any custom Sass that calls these functions or mixins.
+- **CSS variable prefixing now handled by PostCSS.** The `$prefix` Sass variable has been removed. CSS custom properties are now written without a prefix in the Sass source and prefixed automatically via `postcss-prefix-custom-properties` during the build. To customize the prefix, update your PostCSS configuration instead of Sass.
+- **Removed RFS (Responsive Font Sizes).** The `scss/vendor/_rfs.scss` file and all RFS mixins have been removed. Typography now uses fixed `rem` values and `clamp()` for responsive sizing. If you relied on RFS for automatic font scaling, you'll need to implement your own responsive typography or use `clamp()` directly.
+- **Renamed Sass files for consistency.** `_placeholders.scss` is now `_placeholder.scss` and `_spinners.scss` is now `_spinner.scss`. Update any individual `@use` imports for these files.
+- **Standardized focus styles with `focus-ring` mixin.** All component-specific `*-focus-box-shadow` Sass variables (e.g., `$btn-focus-box-shadow`, `$input-focus-box-shadow`, `$accordion-button-focus-box-shadow`) have been removed. Focus styles are now handled by a shared `@mixin focus-ring()` using `--focus-ring`, `--focus-ring-width`, `--focus-ring-offset`, and `--focus-ring-color` CSS custom properties. Customize focus styles by overriding these tokens in `_root.scss` instead of individual Sass variables.
+- **Renamed `$grid-breakpoints` to `$breakpoints`.**
+- **Removes all deprecated Sass variables and values:**
+ - Removed `$nested-kbd-font-weight`, no replacement.
+ - Removed `muted`, `black-50`, and `white-50` from text colors utilities map
+ - Consolidated carousel dark variables, removing `$carousel-dark-indicator-active-bg`, `$carousel-dark-caption-color`, and `$carousel-dark-control-icon-filter` for their reassigned counterparts.
+ - Removed `$btn-close-white-filter` for `$btn-close-filter-dark`.
+ - Removed `$border-radius-xxl`, use `$border-radius-2xl`.
+ - Removed `$text-muted` for secondary color.
+ - Removed `$hr-bg-color` for `$hr-border-color` and `$hr-height` for `$hr-border-width`.
+ - Renamed `$zindex-dropdown` to `$zindex-menu`.
+ - Removed unused `$dropdown-header-padding` for the `-x`/`-y` split variables.
+ - Removed unused `$accordion-button-focus-border-color`.
+ - Removed unused `$tooltip-arrow-color`.
+ - Removed unused `$popover-arrow-color` and `$popover-arrow-outer-color`
+ - Removed unused `$alert-bg-scale`, `$alert-border-scale`, and `$alert-color-scale` (replaced by theme tokens)
+ - Removed unused `$list-group-item-bg-scale` and `$list-group-item-color-scale` (replaced by theme tokens)
+
+### JavaScript
+
+- **Bootstrap's JavaScript is now ESM-only.** We no longer ship UMD bundles. All dist files (`bootstrap.js`, `bootstrap.bundle.js`, and their minified versions) are native ES modules. The plugin APIs themselves are unchanged—only how you load and reference them is different.
+ - CDN `<script>` tags must add `type="module"`:
+ ```html
+ <script type="module" src="bootstrap.bundle.min.js"></script>
+ ```
+ - In v5, the UMD bundle automatically created a `window.bootstrap` global. ES modules don't do this, so there is no longer a `bootstrap` global object. If you called plugin APIs through the global namespace, you must update to explicit imports:
+
+ **Before (v5):**
+ ```js
+ const tooltip = bootstrap.Tooltip.getOrCreateInstance(el)
+ ```
+
+ **After (v6):**
+ ```js
+ import { Tooltip } from './bootstrap.bundle.min.js'
+ const tooltip = Tooltip.getOrCreateInstance(el)
+ ```
+ - **Data attribute APIs are unchanged.** If you only use `data-bs-toggle`, `data-bs-dismiss`, and other data attributes—without calling the JavaScript API directly—the only change you need is adding `type="module"` to your script tag. All data attribute behavior continues to work automatically.
+ - For modern ESM-based bundler setups (Vite, Webpack 5, Parcel 2, Rollup, etc.), no changes are needed — `import { Tooltip } from 'bootstrap'` works as before and now supports full tree shaking. Projects still using CommonJS `require()` calls will need to update to ESM `import` syntax.
+- Removed the separate `bootstrap.esm.js` and `bootstrap.esm.min.js` files — `bootstrap.js` is now the ESM entry point.
+- Removed `js/index.umd.js` entry point.
+- Removed jQuery support and the `js-test-jquery` test target.
+- **Replaced the Dropdown component with Menu.** All `.dropdown-*` classes are now `.menu-*` classes, and `data-bs-toggle="dropdown"` is now `data-bs-toggle="menu"`. See the [Menu docs]([[docsref:/components/menus]]) for full details.
+ - Renamed CSS classes: `.dropdown-menu` to `.menu`, `.dropdown-item` to `.menu-item`, `.dropdown-divider` to `.menu-divider`, `.dropdown-header` to `.menu-header`, `.dropdown-submenu` to `.submenu`.
+ - Removed the `.dropdown-toggle` class — menu toggles no longer require a toggle class.
+ - Removed the `.dropdown` wrapper — no wrapper element is required. The toggle and `.menu` are direct siblings.
+ - Simplified markup from `<ul><li><a class="dropdown-item">` to a flat `<div class="menu"><a class="menu-item">` structure.
+ - Removed `.dropdown-toggle-split` — button group border radius for split menus is now handled automatically via `:has(+ .menu)`.
+ - Renamed the JavaScript export from `Dropdown` to `Menu` — update imports to `import { Menu } from 'bootstrap'`.
+ - Renamed events: `show.bs.dropdown` to `show.bs.menu`, `shown.bs.dropdown` to `shown.bs.menu`, `hide.bs.dropdown` to `hide.bs.menu`, `hidden.bs.dropdown` to `hidden.bs.menu`.
+ - Renamed the data key from `bs.dropdown` to `bs.menu` (affects `Menu.getInstance()` and `Menu.getOrCreateInstance()`).
+- **Added new Combobox component.** A searchable select built on top of Menu, with single and multi-select support. See the [Combobox docs]([[docsref:/forms/combobox]]).
+- Replaced Popper.js (`@popperjs/core`) with [Floating UI](https://floating-ui.com/) (`@floating-ui/dom`) for menu, tooltip, and popover positioning. The `popperConfig` option on Tooltip, Popover, and Menu (formerly Dropdown) has been renamed to `floatingConfig`. Update any custom positioning configuration accordingly.
+- Added [Vanilla Calendar Pro](https://vanilla-calendar.pro/) (`vanilla-calendar-pro`) as a peer dependency for the new Datepicker component.
+- Removed the `jspm` configuration from `package.json`.
+- Added `"sideEffects"` metadata to `package.json` to enable tree shaking in bundlers while preserving the Data API event listeners that Bootstrap's plugins register at the top level.
+- Added `"exports"` map to `package.json` for explicit subpath access to source, dist, and Sass files.
+
+### Components
+
+- **Replaced the Modal component with Dialog.** Dialog is built on the native `<dialog>` element, using `showModal()` / `show()` / `close()` browser APIs. The markup, classes, data attributes, events, CSS variables, and JavaScript API have all changed:
+ - Markup: The `.modal` > `.modal-dialog` > `.modal-content` wrapper structure has been replaced by a single `<dialog class="dialog">` element. Body sections use `.dialog-header`, `.dialog-body`, and `.dialog-footer` directly inside the `<dialog>`.
+ - CSS classes: `.modal` → `.dialog`, `.modal-header` → `.dialog-header`, `.modal-body` → `.dialog-body`, `.modal-footer` → `.dialog-footer`, `.modal-title` → `.dialog-title`. The `.modal-dialog` and `.modal-content` wrapper classes have been removed entirely.
+ - Sizes: `.modal-sm` → `.dialog-sm`, `.modal-lg` → `.dialog-lg`, `.modal-xl` → `.dialog-xl`, `.modal-fullscreen` → `.dialog-fullscreen`.
+ - Data attributes: `data-bs-toggle="modal"` → `data-bs-toggle="dialog"`, `data-bs-dismiss="modal"` → `data-bs-dismiss="dialog"`.
+ - JavaScript: `Modal` → `Dialog` — update imports to `import { Dialog } from 'bootstrap'`.
+ - Events: `show.bs.modal` → `show.bs.dialog`, `shown.bs.modal` → `shown.bs.dialog`, `hide.bs.modal` → `hide.bs.dialog`, `hidden.bs.modal` → `hidden.bs.dialog`, `hidePrevented.bs.modal` → `hidePrevented.bs.dialog`.
+ - Data key: `bs.modal` → `bs.dialog` (affects `Dialog.getInstance()` and `Dialog.getOrCreateInstance()`).
+ - CSS variables: `--modal-*` → `--dialog-*`.
+ - Backdrop: The `.modal-backdrop` DOM element is gone — Dialog uses the native `::backdrop` pseudo-element with `backdrop-filter: blur()` support.
+ - Body scroll prevention: `.modal-open` on `<body>` → `.dialog-open` on the `<html>` element.
+ - New variant classes: `.dialog-slide-up`, `.dialog-slide-down` (slide animations), `.dialog-instant` (no animation), `.dialog-static` (static backdrop bounce), `.dialog-nonmodal` (non-modal positioning), `.dialog-scrollable`, `.dialog-overflow`.
+ - Non-modal support: Set `modal: false` or `data-bs-modal="false"` for non-modal dialogs.
+ - Dialog swapping: Triggers inside an open dialog can open a new dialog and close the current one automatically.
+ - See the [Dialog docs]([[docsref:/components/dialog]]) for full details.
+- **Offcanvas renamed to Drawer.** All class names, data attributes, events, CSS variables, and JavaScript APIs have been renamed:
+ - CSS classes: `.offcanvas` → `.drawer`, `.offcanvas-start` → `.drawer-start`, `.offcanvas-header` → `.drawer-header`, etc.
+ - Data attributes: `data-bs-toggle="offcanvas"` → `data-bs-toggle="drawer"`, `data-bs-dismiss="offcanvas"` → `data-bs-dismiss="drawer"`
+ - JavaScript: `bootstrap.Offcanvas` → `bootstrap.Drawer`
+ - Events: `show.bs.offcanvas` → `show.bs.drawer`, etc.
+ - CSS variables: `--offcanvas-*` → `--drawer-*`
+ - Sass: `$zindex-offcanvas` → `$zindex-drawer`
+- **New `.drawer-sheet` variant** for flush-to-edge panels with no inset, border-radius, or shadow.
+- **Swipe-to-dismiss** gesture support on touch devices for Drawer components. Drawers automatically detect their placement and dismiss on the appropriate swipe direction.
+- **Dialog and Drawer share `DialogBase`** — the show/hide/toggle lifecycle, keyboard handling, backdrop clicks, and static backdrop bounce are consolidated in a shared base class.
+- **Reworked button variants.** The v5 per-color classes like `.btn-primary`, `.btn-outline-primary`, `.btn-secondary`, etc. are replaced by a composition of variant + theme classes:
+ - `.btn-primary` → `.btn-solid .theme-primary`
+ - `.btn-outline-primary` → `.btn-outline .theme-primary`
+ - New variant classes: `.btn-solid`, `.btn-outline`, `.btn-subtle`, `.btn-text`, plus `.btn-styled` for gradient/shadow depth and `.btn-link` for link-style buttons.
+ - Color is applied via `.theme-*` utility classes (e.g., `.theme-primary`, `.theme-danger`, `.theme-success`) rather than being baked into each button class.
+ - Shared sizing tokens: Buttons and inputs now share `--btn-input-*` CSS variables for consistent sizing.
+ - New `.btn-icon` class for square icon-only buttons with `aspect-ratio: 1`.
+ - Added `xs` button size (`.btn-xs`).
+- **Rebuilt accordion on native `<details>` / `<summary>`.** The markup structure has fundamentally changed:
+ - v5: `.accordion-item` > `.accordion-header` > `button.accordion-button` + `.accordion-collapse` > `.accordion-body`, controlled by the Collapse JavaScript plugin.
+ - v6: `<details class="accordion-item">` > `<summary class="accordion-header">` + `<div class="accordion-body">`, using the browser's native disclosure widget. No JavaScript dependency for basic open/close behavior.
+ - Exclusive accordion groups (only one item open) are handled via the HTML `name` attribute on `<details>` elements, replacing the `data-bs-parent` approach.
+ - The `.accordion-button` and `.accordion-collapse` classes have been removed.
+ - The expand/collapse icon now uses an `.accordion-icon` element (typically an SVG) inside the summary, replacing the CSS `background-image` approach.
+ - Open state styling uses `details[open]` instead of JavaScript-toggled classes.
+ - Theme coloring via `.theme-*` classes on the `.accordion` wrapper.
+- **Rebuilt close button markup.** `.btn-close` now expects a child `<svg>` element with `fill: currentcolor` instead of the v5 `background-image` encoded SVG. The filter-based dark mode approach (`$btn-close-white-filter`) has been replaced by `currentcolor` inheritance.
+- **Restructured cards.** Borders now live on `.card-body` and `.card-list` segments rather than a single outer `.card` border. Added `--card-box-shadow` and `--card-body-gap` tokens. New variant classes: `.card-translucent` (frosted glass effect) and `.card-subtle` (themed with subtle backgrounds). Horizontal cards use a new `.card-row` class.
+- **Reworked badge variants.** Badge color variants now use `.badge-subtle` and `.badge-outline` combined with `.theme-*` classes (e.g., `.badge-subtle .theme-primary`), replacing the v5 `.bg-primary` utility pattern on badges.
+- **Updated breadcrumb markup.** Breadcrumbs now use `.breadcrumb-link` as an interactive element with padding, min-height, and hover background, and `.breadcrumb-divider` as a visible separator element between items. The v5 `::before` pseudo-element divider pattern has been removed.
+
+### Reboot
+
+- Relocated heading classes (like `.h1`) and some type classes (`.mark` and `.small`) to Reboot from `_type.scss`. This avoids a dependency in Sass modules and we like to avoid extending selectors in general.
+- Removed the `::-moz-focus-inner` styles, as the pseudo selector is deprecated in Firefox.
+- Removed `text-transform: none` from `button` and `select` elements, as Firefox no longer incorrectly inherits text-transform.
+- Added `accent-color: var(--primary-base)` on `:root`, which applies the primary theme color to native form controls (checkboxes, radios, range inputs, progress bars) globally.
+
+### Forms
+
+- **Refactor checks, radios, and switches.**
+ - Split apart `_form-check.scss` into separate stylesheets: `_checkbox.scss`, `_radio.scss`, and `_switch.scss`.
+ - Also split apart the documentation pages for checks, radios, and switches.
+ - Added new CSS variables on each of these components. _Side note: we could've shared variables here, but chose not to for simplicity's sake._
+ - Removed several now unused Sass variables.
+ - Checkboxes now have a wrapping element and an SVG in the DOM for checked and indeterminate states. Radios and switches do not.
+ - Revamped layout for checks, radios, and switches with labels (and descriptions). We now have custom elements for layout that include basic flexbox styling.
+ - Refactored toggle buttons to use a nested input structure. The `.btn-check` class now goes on the label (not the input), with the input nested inside. This eliminates the need for `id`/`for` attributes and uses CSS `:has()` selector instead of sibling selectors. Example: `<label class="btn-check btn-solid theme-primary"><input type="checkbox">Toggle</label>`.
+- **Consolidate `.form-select` into `.form-control`.**
+ - Removed `.form-select`—use `.form-control` on `<select>` elements now. Too much abstraction and duplication at the same time.
+ - Adds new CSS variables on `.form-control` for easier customization without Sass compilation.
+ - `.form-control` now has a `min-height` at all times as opposed to just on `<textarea>` elements. This reduces some CSS for us.
+- **Added new Combobox form component.** A searchable, filterable select with single and multi-select modes, built on top of the Menu component. See the [Combobox docs]([[docsref:/forms/combobox]]).
+
+### Helpers
+
+- Ratio helpers have been moved to utilities.
+- Dropped clearfix helper for `.d-flow-root` utility.
+
+### Utilities
+
+- **Expanded spacer scale.** The `$spacers` map has been expanded from 6 steps (0–5) to 10 steps (0–9) with finer granularity. Note that spacer keys no longer map to the same values as v5:
+
+<BsTable>
+| Key | v5 value | v6 value |
+|---|---|---|
+| 0 | `0` | `0` |
+| 1 | `0.25rem` | `0.25rem` |
+| 2 | `0.5rem` | `0.5rem` |
+| 3 | `1rem` | `0.75rem` (new) |
+| 4 | `1.5rem` | `1rem` (was key 3) |
+| 5 | `3rem` | `1.25rem` (new) |
+| 6 | — | `1.5rem` (was key 4) |
+| 7 | — | `2rem` (new) |
+| 8 | — | `2.5rem` (new) |
+| 9 | — | `3rem` (was key 5) |
+</BsTable>
+
+- **New fixed-size scale.** A new `$sizes` map (keys 1–12) provides fixed rem-based widths, merged into the width utility. v5 had no equivalent fixed-size scale in `$sizes`—it only had percentage-based values.
+
+<BsTable>
+| Key | v5 `$sizes` | v6 `$sizes` |
+|---|---|---|
+| 1 | — | `1rem` |
+| 2 | — | `2rem` |
+| 3 | — | `3rem` |
+| 4 | — | `4rem` |
+| 5 | — | `5rem` |
+| 6 | — | `6rem` |
+| 7 | — | `7rem` |
+| 8 | — | `8rem` |
+| 9 | — | `9rem` |
+| 10 | — | `10rem` |
+| 11 | — | `11rem` |
+| 12 | — | `12rem` |
+| 25 | `25%` | `25%` (in width utility) |
+| 50 | `50%` | `50%` (in width utility) |
+| 75 | `75%` | `75%` (in width utility) |
+| 100 | `100%` | `100%` (in width utility) |
+| auto | `auto` | `auto` (in width utility) |
+</BsTable>
+
+- **Font size scale reworked.** `.fs-1` through `.fs-6` (numeric, descending size) have been replaced by t-shirt size keys from `.fs-xs` through `.fs-6xl` (10 steps, ascending). Larger sizes use `clamp()` for responsive scaling. New `.text-{size}` utilities set both `font-size` and `line-height` together.
+
+<BsTable>
+| v5 class | v5 value | v6 class | v6 value |
+|---|---|---|---|
+| `.fs-6` | `1rem` | `.fs-md` | `1rem` |
+| `.fs-5` | `1.25rem` | `.fs-lg` | `clamp(1.25rem, …, 1.5rem)` |
+| `.fs-4` | `1.5rem` | `.fs-xl` | `clamp(1.5rem, …, 1.75rem)` |
+| `.fs-3` | `1.75rem` | `.fs-2xl` | `clamp(1.75rem, …, 2rem)` |
+| `.fs-2` | `2rem` | `.fs-3xl` | `clamp(2rem, …, 2.5rem)` |
+| `.fs-1` | `2.5rem` | `.fs-4xl` | `clamp(2.25rem, …, 3rem)` |
+| — | — | `.fs-xs` | `0.75rem` |
+| — | — | `.fs-sm` | `0.875rem` |
+| — | — | `.fs-5xl` | `clamp(3rem, …, 4rem)` |
+| — | — | `.fs-6xl` | `clamp(3.75rem, …, 5rem)` |
+</BsTable>
+
+- **Border radius scale updated.** The underlying CSS custom property values have increased, and the utility mapping has shifted:
+
+<BsTable>
+| Utility class | v5 variable | v5 value | v6 variable | v6 value |
+|---|---|---|---|---|
+| `.rounded` | `$border-radius` | `0.375rem` | `--border-radius` | `0.5rem` |
+| `.rounded-0` | — | `0` | — | `0` |
+| `.rounded-1` | `$border-radius-sm` | `0.25rem` | `--border-radius-sm` | `0.5rem` |
+| `.rounded-2` | `$border-radius` | `0.375rem` | `--border-radius` | `0.5rem` |
+| `.rounded-3` | `$border-radius-lg` | `0.5rem` | `--border-radius-lg` | `0.75rem` |
+| `.rounded-4` | `$border-radius-xl` | `1rem` | `--border-radius-xl` | `1rem` |
+| `.rounded-5` | `$border-radius-xxl` | `2rem` | `--border-radius-2xl` | `2rem` |
+</BsTable>
+
+- **Font weight additions.** Added `.fw-medium` (`500`) and `.fw-semibold` (`600`) utilities. v5 only had `lighter`, `light` (`300`), `normal` (`400`), `bold` (`700`), and `bolder`.
+- **Negative margins limited.** Negative spacers are reduced to only `-1` (`-0.25rem`) and `-2` (`-0.5rem`), and only applied to `margin-inline-start` (`.ms-n1`, `.ms-n2`). The v5 full negative margin utilities across all sides have been removed.
+- **Spacing and border utilities now use CSS logical properties.** `margin-top` → `margin-block-start`, `margin-right` → `margin-inline-end`, `padding-left` → `padding-inline-start`, `border-right` → `border-inline-end`, etc. Class names (`.mt-*`, `.me-*`, `.ps-*`, `.border-end`) remain the same, but the underlying CSS properties are now logical, improving RTL and writing-mode support.
+- **Text wrap additions.** Added `.text-balance` and `.text-pretty` values to the text-wrap utility.
+- **Color utility renames.** `.text-*` color utilities have been replaced by `.fg-*` (foreground) utilities. New `.fg-emphasis-*` and `.fg-contrast-*` variants. Background utilities now include `.bg-subtle-*` and `.bg-muted-*` in addition to `.bg-*`.
+- **Display utilities:** added `flow-root` and `contents` options.
+- **Sizing utilities:**
+ - Renamed `.mh-*`/`.mw-*` to `.max-h-*`/`.max-w-*`
+ - Added `.min-h-*` and `.min-w-*` utilities with two default values, `0` and `100%`
+ - Added `auto`, `min-content`, `max-content`, and `fit-content` to `width` and `height` utilities.
+- **Flex & Grid utilities:**
+ - Added `.place-items` and `.justify-items` utilities.
+ - Added `.grid-cols-*` utilities for `grid-template-columns` (1–4 and 6 column layouts), `.grid-cols-fill` for spanning all columns, and `.grid-auto-flow` utility.
+- **Container query utilities.** New `.contains-inline` and `.contains-size` utilities for `container-type`.
+- Ratio helpers are now powered by the utility API and use simplified values without `calc()`.
+
+### New components and plugins
+
+- **Dialog** — replaces Modal, built on the native `<dialog>` element. See the Components section above for the full migration.
+- **Stepper** — new `.stepper` component for multi-step workflows with `.stepper-item` and `.stepper-horizontal` variant. CSS-only.
+- **Avatar** — new `.avatar` component with sizes (`.avatar-xs` through `.avatar-xl`), status indicators (`.avatar-status .status-online|offline|busy|away`), subtle variant, and `.avatar-stack` for grouped avatars.
+- **Chip and Chip Input** — new `.chip` component for tags/tokens and `.chip-input` for interactive chip entry. `ChipInput` JavaScript plugin with events: `add.bs.chip-input`, `remove.bs.chip-input`, `change.bs.chip-input`.
+- **OTP Input** — new `.otp` component for one-time password fields. `OtpInput` JavaScript plugin with events: `input.bs.otp-input`, `complete.bs.otp-input`.
+- **Password Strength** — `Strength` JavaScript plugin for password strength metering with `strengthChange.bs.strength` event.
+- **Toggler** — `Toggler` JavaScript plugin for toggling classes or attributes on elements via `data-bs-toggle="toggler"`.
+- **Datepicker** — `Datepicker` JavaScript plugin built on Vanilla Calendar Pro, with events: `change.bs.datepicker`, `show.bs.datepicker`, `hide.bs.datepicker`.
+- **Form Adorn** — new `.form-adorn` component for adding icons or text decoration to form inputs.
+- **Prose** — new `.prose` class for rich typography scoping and `.not-prose` to opt out of prose styles within a prose container.
+- **NavOverflow** — `NavOverflow` JavaScript plugin for handling overflowing navigation items.
+- **Submenu** — nested menu support via `.submenu` class within Menu, with `submenuTrigger` (`hover`, `click`, or `both`) and `submenuDelay` options. Mobile-friendly stacking with `.submenu-stacked` and `.submenu-back`.
+
+### Docs
+
+- Removed all `AddedIn` badges.
+- Rearranged utilities documentation to break apart larger pages that included groups of utilities. Sizing, spacing, flex, type, and more have been broken out into smaller pages with new sub-group headings in the sidebar.
+++ /dev/null
----
-title: Migrating to v6
-description: Track and review changes to the Bootstrap source files, documentation, and components to help you migrate from v5 to v6.
-aliases: "/migration/"
-toc: true
----
-
-## v6.0.0 Migration
-
-Bootstrap 6 is a major release with many breaking changes to modernize our codebase, adopt newer build tools, and improve customization. Keep reading for a guide on how to migrate from v5 to v6, and a full changelog of what's new.
-
-1. Bump your Bootstrap dependency:
-
- ```json
- {
- "dependencies": {
- "bootstrap": "^6.0.0"
- }
- }
- ```
-
-2. If using all of Bootstrap's Sass files, include it in your Sass using `@use`:
-
- ```scss
- @use "bootstrap/scss/bootstrap";
- ```
-
- With this, you can then easily override Bootstrap's Sass variables and maps:
-
- ```scss
- @use "bootstrap/scss/bootstrap" with (
- $spacer: 1rem,
- $enable-reduced-motion: true,
- );
- ```
-
-3. If using only certain parts of Bootstrap's Sass files, you can use `@use` to import them individually. Be aware that our Sass file structure has changed and you may need to adjust your imports accordingly.
-
- ```scss
- @use "bootstrap/scss/forms";
- ```
-
-4. Update HTML and CSS per the changelog and updates in the documentation.
-
-5. Recompile your Sass to see the changes.
-
-## v6.0.0 Changelog
-
-### CSS
-
-- **Implemented CSS layers** in `_root.scss` and applied them to all our Sass files.
- - Layers are set in `_root.scss` and then utilized across separate Sass partials.
- - We cannot, unfortunately, wrap `@use` or `@forward` statements in `@layer`—Sass expects those to be top level at all times. Also, while CSS allows `@import "file.css" layer(name)`, Sass also does not support that.
-- Clarified and simplified CSS-Sass setup.
-- New, streamlined color modes and theming.
- - Removed `_maps.scss`
- - Removed `_variables-dark.scss`
- - Added `_colors.scss`, splitting colors out to their own file
- - Removed `_variables.scss`, consolidating all variables into `_config.scss`
- - Added `_theme.scss` where we setup all our global theming for how colors are applied
-- **Updated lg, xl, and 2xl breakpoints and containers.**
- - Increased the `lg` breakpoint from 992px to 1024px; it's container remains the same at 960px.
- - Increased the `xl` breakpoint from 1200px to 1280px, and it's container from 1140px to 1200px.
- - Renamed `xxl` to `2xl` for better scaling with additional custom breakpoints
- - Increased the `2xl` breakpoint from 1400px to 1536px, and it's container from 1320px to 1440px.
-- **Responsive classes now use a breakpoint prefix instead of an infix.** Class names follow the Tailwind-style `breakpoint:class` pattern (e.g., `md:d-none` instead of `d-md-none`). In HTML, use the unescaped colon: `class="md:d-none"`. This applies to utilities, grid, and all responsive components.
-
-<BsTable>
-| Category | Before (v5) | After (v6) |
-|---|---|---|
-| Utilities | `.d-md-none`, `.p-lg-3` | `.md:d-none`, `.lg:p-3` |
-| Grid columns | `.col-md-6` | `.md:col-6` |
-| Row columns | `.row-cols-md-3` | `.md:row-cols-3` |
-| Offsets | `.offset-md-2` | `.md:offset-2` |
-| Gutters | `.g-md-3`, `.gx-md-3` | `.md:g-3`, `.md:gx-3` |
-| CSS Grid | `.g-col-md-4` | `.md:g-col-4` |
-| Containers | `.container-sm` | `.sm:container` |
-| Navbar | `.navbar-expand-md` | `.md:navbar-expand` |
-| Drawer | `.offcanvas-md` | `.md:drawer` |
-| Tables | `.table-responsive-md` | `.md:table-responsive` |
-| List group | `.list-group-horizontal-md` | `.md:list-group-horizontal` |
-| Sticky | `.sticky-md-top` | `.md:sticky-top` |
-| Stacks | `.vstack-md` | `.md:vstack` |
-| Stepper | `.stepper-horizontal-md` | `.md:stepper-horizontal` |
-| Dialog | `.dialog-fullscreen-sm-down` | `.sm-down:dialog-fullscreen` |
-| Print | `.d-print-none` | `.print:d-none` |
-</BsTable>
-
-### Sass
-
-- Dropped support for Node Sass, including no longer testing any of our source CSS against it.
- - Rearranged several Sass files in the process.
-- Removed `add()` and `subtract()` functions. Use `calc()` instead.
-- Removed `create-css-vars()` mixin (unused).
-- **Renamed `breakpoint-infix()` to `breakpoint-prefix()`.** The function now returns a prefix string (e.g., `"md\:"`) instead of an infix (e.g., `"-md"`). The `loop-breakpoints-up` and `loop-breakpoints-down` mixins now expose `$prefix` instead of `$infix`. Update any custom Sass that calls these functions or mixins.
-- **CSS variable prefixing now handled by PostCSS.** The `$prefix` Sass variable has been removed. CSS custom properties are now written without a prefix in the Sass source and prefixed automatically via `postcss-prefix-custom-properties` during the build. To customize the prefix, update your PostCSS configuration instead of Sass.
-- **Removes all deprecated Sass variables and values:**
- - Removed `$nested-kbd-font-weight`, no replacement.
- - Removed `muted`, `black-50`, and `white-50` from text colors utilities map
- - Consolidated carousel dark variables, removing `$carousel-dark-indicator-active-bg`, `$carousel-dark-caption-color`, and `$carousel-dark-control-icon-filter` for their reassigned counterparts.
- - Removed `$btn-close-white-filter` for `$btn-close-filter-dark`.
- - Removed `$border-radius-xxl`, use `$border-radius-2xl`.
- - Removed `$text-muted` for secondary color.
- - Removed `$hr-bg-color` for `$hr-border-color` and `$hr-height` for `$hr-border-width`.
- - Renamed `$zindex-dropdown` to `$zindex-menu`.
- - Removed unused `$dropdown-header-padding` for the `-x`/`-y` split variables.
- - Removed unused `$accordion-button-focus-border-color`.
- - Removed unused `$tooltip-arrow-color`.
- - Removed unused `$popover-arrow-color` and `$popover-arrow-outer-color`
- - Removed unused `$alert-bg-scale`, `$alert-border-scale`, and `$alert-color-scale` (replaced by theme tokens)
- - Removed unused `$list-group-item-bg-scale` and `$list-group-item-color-scale` (replaced by theme tokens)
-
-### JavaScript
-
-- **Bootstrap's JavaScript is now ESM-only.** We no longer ship UMD bundles. All dist files (`bootstrap.js`, `bootstrap.bundle.js`, and their minified versions) are native ES modules. The plugin APIs themselves are unchanged—only how you load and reference them is different.
- - CDN `<script>` tags must add `type="module"`:
- ```html
- <script type="module" src="bootstrap.bundle.min.js"></script>
- ```
- - In v5, the UMD bundle automatically created a `window.bootstrap` global. ES modules don't do this, so there is no longer a `bootstrap` global object. If you called plugin APIs through the global namespace, you must update to explicit imports:
-
- **Before (v5):**
- ```js
- const tooltip = bootstrap.Tooltip.getOrCreateInstance(el)
- ```
-
- **After (v6):**
- ```js
- import { Tooltip } from './bootstrap.bundle.min.js'
- const tooltip = Tooltip.getOrCreateInstance(el)
- ```
- - **Data attribute APIs are unchanged.** If you only use `data-bs-toggle`, `data-bs-dismiss`, and other data attributes—without calling the JavaScript API directly—the only change you need is adding `type="module"` to your script tag. All data attribute behavior continues to work automatically.
- - For modern ESM-based bundler setups (Vite, Webpack 5, Parcel 2, Rollup, etc.), no changes are needed — `import { Tooltip } from 'bootstrap'` works as before and now supports full tree shaking. Projects still using CommonJS `require()` calls will need to update to ESM `import` syntax.
-- Removed the separate `bootstrap.esm.js` and `bootstrap.esm.min.js` files — `bootstrap.js` is now the ESM entry point.
-- Removed `js/index.umd.js` entry point.
-- Removed jQuery support and the `js-test-jquery` test target.
-- **Replaced the Dropdown component with Menu.** All `.dropdown-*` classes are now `.menu-*` classes, and `data-bs-toggle="dropdown"` is now `data-bs-toggle="menu"`. See the [Menu docs]([[docsref:/components/menus]]) for full details.
- - Renamed CSS classes: `.dropdown-menu` to `.menu`, `.dropdown-item` to `.menu-item`, `.dropdown-divider` to `.menu-divider`, `.dropdown-header` to `.menu-header`, `.dropdown-submenu` to `.submenu`.
- - Removed the `.dropdown-toggle` class — menu toggles no longer require a toggle class.
- - Removed the `.dropdown` wrapper — no wrapper element is required. The toggle and `.menu` are direct siblings.
- - Simplified markup from `<ul><li><a class="dropdown-item">` to a flat `<div class="menu"><a class="menu-item">` structure.
- - Removed `.dropdown-toggle-split` — button group border radius for split menus is now handled automatically via `:has(+ .menu)`.
- - Renamed the JavaScript export from `Dropdown` to `Menu` — update imports to `import { Menu } from 'bootstrap'`.
- - Renamed events: `show.bs.dropdown` to `show.bs.menu`, `shown.bs.dropdown` to `shown.bs.menu`, `hide.bs.dropdown` to `hide.bs.menu`, `hidden.bs.dropdown` to `hidden.bs.menu`.
- - Renamed the data key from `bs.dropdown` to `bs.menu` (affects `Menu.getInstance()` and `Menu.getOrCreateInstance()`).
-- **Added new Combobox component.** A searchable select built on top of Menu, with single and multi-select support. See the [Combobox docs]([[docsref:/forms/combobox]]).
-- Replaced Popper.js (`@popperjs/core`) with [Floating UI](https://floating-ui.com/) (`@floating-ui/dom`) for menu, tooltip, and popover positioning.
-- Added [Vanilla Calendar Pro](https://vanilla-calendar.pro/) (`vanilla-calendar-pro`) as a peer dependency for the new Datepicker component.
-- Removed the `jspm` configuration from `package.json`.
-- Added `"sideEffects"` metadata to `package.json` to enable tree shaking in bundlers while preserving the Data API event listeners that Bootstrap's plugins register at the top level.
-- Added `"exports"` map to `package.json` for explicit subpath access to source, dist, and Sass files.
-
-### Components
-
-- **Offcanvas renamed to Drawer.** All class names, data attributes, events, CSS variables, and JavaScript APIs have been renamed:
- - CSS classes: `.offcanvas` → `.drawer`, `.offcanvas-start` → `.drawer-start`, `.offcanvas-header` → `.drawer-header`, etc.
- - Data attributes: `data-bs-toggle="offcanvas"` → `data-bs-toggle="drawer"`, `data-bs-dismiss="offcanvas"` → `data-bs-dismiss="drawer"`
- - JavaScript: `bootstrap.Offcanvas` → `bootstrap.Drawer`
- - Events: `show.bs.offcanvas` → `show.bs.drawer`, etc.
- - CSS variables: `--offcanvas-*` → `--drawer-*`
- - Sass: `$zindex-offcanvas` → `$zindex-drawer`
-- **New `.drawer-sheet` variant** for flush-to-edge panels with no inset, border-radius, or shadow.
-- **Swipe-to-dismiss** gesture support on touch devices for Drawer components. Drawers automatically detect their placement and dismiss on the appropriate swipe direction.
-- **Dialog and Drawer share `DialogBase`** — the show/hide/toggle lifecycle, keyboard handling, backdrop clicks, and static backdrop bounce are consolidated in a shared base class.
-
-### Reboot
-
-- Relocated heading classes (like `.h1`) and some type classes (`.mark` and `.small`) to Reboot from `_type.scss`. This avoids a dependency in Sass modules and we like to avoid extending selectors in general.
-- Removed the `::-moz-focus-inner` styles, as the pseudo selector is deprecated in Firefox.
-- Removed `text-transform: none` from `button` and `select` elements, as Firefox no longer incorrectly inherits text-transform.
-
-### Forms
-
-- **Refactor checks, radios, and switches.**
- - Split apart `_form-check.scss` into separate stylesheets: `_checkbox.scss`, `_radio.scss`, and `_switch.scss`.
- - Also split apart the documentation pages for checks, radios, and switches.
- - Added new CSS variables on each of these components. _Side note: we could've shared variables here, but chose not to for simplicity's sake._
- - Removed several now unused Sass variables.
- - Checkboxes now have a wrapping element and an SVG in the DOM for checked and indeterminate states. Radios and switches do not.
- - Revamped layout for checks, radios, and switches with labels (and descriptions). We now have custom elements for layout that include basic flexbox styling.
- - Refactored toggle buttons to use a nested input structure. The `.btn-check` class now goes on the label (not the input), with the input nested inside. This eliminates the need for `id`/`for` attributes and uses CSS `:has()` selector instead of sibling selectors. Example: `<label class="btn-check btn-solid theme-primary"><input type="checkbox">Toggle</label>`.
-- **Consolidate `.form-select` into `.form-control`.**
- - Removed `.form-select`—use `.form-control` on `<select>` elements now. Too much abstraction and duplication at the same time.
- - Adds new CSS variables on `.form-control` for easier customization without Sass compilation.
- - `.form-control` now has a `min-height` at all times as opposed to just on `<textarea>` elements. This reduces some CSS for us.
-- **Added new Combobox form component.** A searchable, filterable select with single and multi-select modes, built on top of the Menu component. See the [Combobox docs]([[docsref:/forms/combobox]]).
-
-### Helpers
-
-- Ratio helpers have been moved to utilities.
-- Dropped clearfix helper for `.d-flow-root` utility.
-
-### Utilities
-
-- Ratio helpers are now powered by the utility API and use simplified values without `calc()`.
-- mdo-do: Need to refactor utilities API if we want to restore the commented out custom ratios.
-- **Display utilities:** added `flow-root` option for a modern clearfix.
-- **Sizing utilities:**
- - Renamed `.mh-*`/`.mw-*` to `.max-h-*`/`.max-w-*`
- - Added `.min-h-*` and `.min-w-*` utilities with two default values, `0` and `100%`
- - Added `auto`, `min-content`, `max-content`, and `fit-content` to `width` and `height` utilities.
-- **Flex & Grid utilities:**
- - Added `.place-items` and `.justify-items` utilities.
-- **Utilities API:** Added new `child-selector` option that enables parent-to-child selector patterns wrapped in `:where()` for zero specificity. Any CSS child/descendant selector can be used.
-- **Space utilities:** Added `.space-x-*` and `.space-y-*` utilities for margin-based spacing between direct children of an element. Responsive variants included.
-- **Divide utilities:** Added `.divide-x` and `.divide-y` utilities for adding borders between direct children of an element, using existing border CSS variables. Responsive variants included.
-
-### Docs
-
-- Removed all `AddedIn` badges.
-- Rearranged utilities documentation to break apart larger pages that included groups of utilities. Sizing, spacing, flex, type, and more have been broken out into smaller pages with new sub-group headings in the sidebar.