Skip to main content Skip to docs navigation

Dialog

A modern component built on the native <dialog> element with built-in accessibility and backdrop support that replaces the old Modal component.

How it works

The Dialog component leverages the browser's native <dialog> element, providing built-in accessibility features, focus management, and backdrop handling without the complexity of custom implementations.

Key features of the native dialog:

  • Native modal behavior via showModal() with automatic focus trapping
  • Built-in backdrop using the ::backdrop pseudo-element
  • Escape key handling closes the dialog by default
  • Accessibility with proper focus management and ARIA attributes
  • Top layer rendering ensures the dialog appears above all other content

Native <dialog> elements support two methods: show() opens the dialog inline without a backdrop or focus trapping, while showModal() opens it as a true modal in the browser's top layer with a backdrop, focus trapping, and Escape key handling. Bootstrap's Dialog component uses showModal() to provide the expected modal experience.

The animation effect of this component is dependent on the prefers-reduced-motion media query. See the reduced motion section of our accessibility documentation.

Example

Toggle a dialog by clicking the button below. The dialog uses the native showModal() API for true modal behavior.

Dialog title

This is a native dialog element. It uses the browser's built-in modal behavior for accessibility and focus management.

The markup for a dialog is straightforward:

HTML
<dialog class="dialog" id="exampleDialog">
  <div class="dialog-header">
    <h1 class="dialog-title">Dialog title</h1>
    <button type="button" class="btn-close" data-bs-dismiss="dialog" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="20" height="20" fill="none">
        <path fill="currentcolor" d="M12 0a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4zm-.646 4.646a.5.5 0 0 0-.707 0L8 7.293 5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.647a.5.5 0 1 0 .708.707L8 8.707l2.647 2.646a.5.5 0 1 0 .707-.707L8.707 8l2.646-2.646a.5.5 0 0 0 0-.708z"/>
      </svg>
    </button>
  </div>
  <div class="dialog-body">
    <p>Dialog body content goes here.</p>
  </div>
  <div class="dialog-footer">
    <button type="button" class="btn btn-solid theme-secondary" data-bs-dismiss="dialog">Close</button>
    <button type="button" class="btn btn-solid theme-primary">Save changes</button>
  </div>
</dialog>

<button type="button" class="btn btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#exampleDialog">
  Open dialog
</button>

Static backdrop

When backdrop is set to static, the dialog will not close when clicking outside of it. Click the button below to try it.

Static backdrop

I will not close if you click outside of me. Use the close button or press Escape.

Scrolling long content

When dialogs have content that exceeds the viewport height, the entire dialog scrolls within the viewport. The header, body, and footer all scroll together.

Scrolling dialog

This is some placeholder content to show the scrolling behavior for dialogs. When the content exceeds the viewport height, you can scroll the entire dialog within the window—the header, body, and footer all move together.

The dialog component is built on the native HTML <dialog> element, which provides built-in accessibility features like focus trapping, backdrop handling, and proper keyboard interactions. This approach leverages browser-native functionality rather than custom JavaScript implementations.

When using showModal(), the dialog is rendered in the browser's top layer, ensuring it appears above all other content regardless of z-index values. The backdrop is created using the ::backdrop pseudo-element, which can be styled with CSS.

Focus management is handled automatically by the browser. When a modal dialog opens, focus moves to the first focusable element inside. When closed, focus returns to the element that triggered the dialog. This behavior is essential for accessibility and keyboard navigation.

The Escape key closes modal dialogs by default, though this can be prevented using the cancel event. Non-modal dialogs opened with show() don't trap focus or block interaction with the rest of the page.

Bootstrap's Dialog component wraps the native element with additional features: custom animations, static backdrop option, programmatic control via JavaScript, and integration with data attributes for declarative usage.

Scrolling behavior varies based on content length. Short dialogs center in the viewport. Long dialogs scroll within the viewport by default, though you can use .dialog-scrollable to scroll only the body while keeping header and footer fixed.

The component fires standard Bootstrap events: show.bs.dialog, shown.bs.dialog, hide.bs.dialog, and hidden.bs.dialog. These allow you to hook into the dialog lifecycle and execute custom logic.

This content should appear at the bottom after you scroll.

You can also create a scrollable dialog that scrolls the dialog body while keeping the header and footer fixed. Add .dialog-scrollable to the .dialog element.

Scrollable body

This is some placeholder content to show the scrolling behavior for dialogs. We use repeated line breaks to demonstrate how content can exceed the dialog's inner height, showing scrolling within the body while the header and footer remain fixed.





























































This content should appear at the bottom after you scroll.

HTML
<!-- Scrollable body dialog -->
<dialog class="dialog dialog-scrollable" id="scrollableBodyDialog">
  <div class="dialog-header">
    <h1 class="dialog-title">Scrollable body</h1>
    <button type="button" class="btn-close" data-bs-dismiss="dialog" aria-label="Close">
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" width="20" height="20" fill="none">
        <path fill="currentcolor" d="M12 0a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H4a4 4 0 0 1-4-4V4a4 4 0 0 1 4-4zm-.646 4.646a.5.5 0 0 0-.707 0L8 7.293 5.354 4.646a.5.5 0 1 0-.708.708L7.293 8l-2.647 2.647a.5.5 0 1 0 .708.707L8 8.707l2.647 2.646a.5.5 0 1 0 .707-.707L8.707 8l2.646-2.646a.5.5 0 0 0 0-.708z"/>
      </svg>
    </button>
  </div>
  <div class="dialog-body">
    <!-- Long content here -->
  </div>
  <div class="dialog-footer">
    <button type="button" class="btn btn-solid theme-secondary" data-bs-dismiss="dialog">Close</button>
  </div>
</dialog>

For a dialog that extends beyond the viewport and scrolls as a whole, add .dialog-overflow and wrap the content in a .dialog-box element. The <dialog> becomes a full-viewport scrollable container, and the .dialog-box is the visual dialog that scrolls up and down.

Overflow dialog

This dialog extends beyond the viewport height. Scroll to see more content. Notice how the entire dialog—including header and footer—shifts up and down as you scroll.

The .dialog-overflow modifier creates a full-viewport scrollable container. The .dialog-box wrapper contains the visual dialog that moves up and down as you scroll. This pattern is useful for very long content like terms of service or detailed forms.

Unlike the default scrolling behavior where the dialog is constrained to the viewport, overflow dialogs can extend beyond it. This gives users a more document-like reading experience for lengthy content.

The backdrop remains fixed while the dialog content scrolls. Clicking outside the dialog box still closes it (unless using a static backdrop). Keyboard navigation and focus trapping work the same as standard dialogs.

Consider using .dialog-scrollable instead if you want the header and footer to remain visible while scrolling. The scrollable variant keeps navigation controls accessible at all times, which may be preferable for forms with submit buttons.

Both approaches leverage the native <dialog> element's top layer rendering. This ensures the dialog appears above all other content, including elements with high z-index values, fixed positioning, or transforms.

The choice between scrolling behaviors depends on your content and user experience goals. Document-like content often works well with overflow scrolling, while interactive content may benefit from fixed header and footer.

You've reached the bottom of the overflow dialog!

HTML
<!-- Overflow dialog (entire dialog scrolls within viewport) -->
<dialog class="dialog dialog-overflow" id="overflowDialog">
  <div class="dialog-box">
    <div class="dialog-header">...</div>
    <div class="dialog-body">
      <!-- Very long content here -->
    </div>
    <div class="dialog-footer">...</div>
  </div>
</dialog>

Swapping dialogs

When a toggle trigger is inside an open dialog, clicking it will swap dialogs—opening the new one before closing the current. This ensures the backdrop stays visible throughout the transition with no flash.

First dialog

Click below to swap to a second dialog. Notice the backdrop stays visible—no flash!

Second dialog

This is the second dialog. You can swap back to the first, or close this one entirely.

The swap behavior is automatic when a data-bs-toggle="dialog" trigger is inside an already-open dialog:

HTML
<!-- First dialog -->
<dialog class="dialog" id="dialog1">
  <div class="dialog-body">
    <p>Click below to swap to dialog 2.</p>
  </div>
  <div class="dialog-footer">
    <!-- This trigger is inside dialog1, so clicking it will swap -->
    <button type="button" class="btn btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#dialog2">
      Go to dialog 2
    </button>
  </div>
</dialog>

<!-- Second dialog -->
<dialog class="dialog" id="dialog2">
  <div class="dialog-body">
    <p>You're now in dialog 2.</p>
  </div>
  <div class="dialog-footer">
    <button type="button" class="btn btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#dialog1">
      Back to dialog 1
    </button>
  </div>
</dialog>

Non-modal dialogs

By default, dialogs open as modals using the native showModal() method. You can also open dialogs as non-modal using show() by setting modal to false. Non-modal dialogs:

  • Have no backdrop
  • Don't trap focus
  • Don't block interaction with the rest of the page
  • Don't render in the browser's top layer
  • Still respond to Escape key (if keyboard: true)

Non-modal dialog

This dialog doesn't block the page. You can still interact with content behind it.

HTML
<button type="button" class="btn btn-solid theme-primary" data-bs-toggle="dialog" data-bs-target="#nonModalDialog" data-bs-modal="false">
  Open non-modal dialog
</button>
JavaScript
const dialog = new bootstrap.Dialog('#myDialog', { modal: false })
dialog.show()

Optional sizes

Dialogs have three optional sizes, available via modifier classes to be placed on a .dialog. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports.

SizeClassDialog max-width
Small.dialog-sm300px
Default500px
Large.dialog-lg800px
Extra large.dialog-xl1140px

Extra large dialog

This is an extra large dialog using the .dialog-xl class.

Large dialog

This is a large dialog using the .dialog-lg class.

Small dialog

This is a small dialog using the .dialog-sm class.

HTML
<dialog class="dialog dialog-xl">...</dialog>
<dialog class="dialog dialog-lg">...</dialog>
<dialog class="dialog dialog-sm">...</dialog>

Fullscreen dialog

Use .dialog-fullscreen to make the dialog cover the entire viewport.

Fullscreen dialog

This dialog covers the entire viewport.

Responsive fullscreen variants are also available. These make the dialog fullscreen only below a specific breakpoint.

ClassFullscreen below
.dialog-fullscreenAlways
.dialog-fullscreen-sm-down576px
.dialog-fullscreen-md-down768px
.dialog-fullscreen-lg-down1024px
.dialog-fullscreen-xl-down1280px
.dialog-fullscreen-2xl-down1536px

Fullscreen below lg

This dialog is fullscreen below the lg breakpoint.

HTML
<dialog class="dialog dialog-fullscreen-lg-down">...</dialog>

JavaScript behavior

Via data attributes

Toggle a dialog without writing JavaScript. Set data-bs-toggle="dialog" on a controller element, like a button, along with a data-bs-target="#foo" to target a specific dialog to toggle.

HTML
<button type="button" data-bs-toggle="dialog" data-bs-target="#myDialog">
  Launch dialog
</button>

Dismiss

Dismissal can be achieved with the data-bs-dismiss attribute on a button within the dialog:

HTML
<button type="button" data-bs-dismiss="dialog">Close</button>

Via JavaScript

Create a dialog with a single line of JavaScript:

JavaScript
const myDialog = new bootstrap.Dialog('#myDialog')

Options

Options can be passed via data attributes or JavaScript. For data attributes, append the option name to data-bs-, as in data-bs-backdrop="static".

NameTypeDefaultDescription
backdropboolean or 'static'trueFor modal dialogs, clicking the backdrop dismisses the dialog. Specify static for a backdrop which doesn't close the dialog when clicked. Has no effect on non-modal dialogs.
keyboardbooleantrueCloses the dialog when escape key is pressed.
modalbooleantrueWhen true, opens the dialog as a modal using showModal() with backdrop, focus trapping, and top layer rendering. When false, opens as a non-modal dialog using show() without backdrop or focus trapping.

Methods

Passing options

Activates your content as a dialog. Accepts an optional options object.

JavaScript
const myDialog = new bootstrap.Dialog('#myDialog', {
  keyboard: false
})
MethodDescription
showOpens the dialog. Returns to the caller before the dialog has actually been shown (i.e. before the shown.bs.dialog event occurs).
hideHides the dialog. Returns to the caller before the dialog has actually been hidden (i.e. before the hidden.bs.dialog event occurs).
toggleToggles the dialog. Returns to the caller before the dialog has actually been shown or hidden (i.e. before the shown.bs.dialog or hidden.bs.dialog event occurs).
handleUpdateProvided for API consistency with Modal. Native dialogs handle their own positioning.
disposeDestroys an element's dialog.
getInstanceStatic method which allows you to get the dialog instance associated with a DOM element.
getOrCreateInstanceStatic method which allows you to get the dialog instance associated with a DOM element, or create a new one in case it wasn't initialized.

Events

Bootstrap's dialog class exposes a few events for hooking into dialog functionality.

EventDescription
show.bs.dialogFires immediately when the show instance method is called.
shown.bs.dialogFired when the dialog has been made visible to the user (will wait for CSS transitions to complete).
hide.bs.dialogFires immediately when the hide instance method is called.
hidden.bs.dialogFired when the dialog has finished being hidden from the user (will wait for CSS transitions to complete).
hidePrevented.bs.dialogFired when the dialog is shown, its backdrop is static, and a click outside the dialog or an escape key press is performed (with keyboard set to false).
cancel.bs.dialogFired when the user presses Escape and the dialog is about to close.
JavaScript
const myDialog = document.getElementById('myDialog')
myDialog.addEventListener('hidden.bs.dialog', event => {
  // do something...
})