Modals
Learn Bootstrap's modal component structure, triggering modals with data-bs-toggle/data-bs-target, sizes, and the JavaScript API.
Introduction
A modal is a dialog box that overlays the current page, forcing the user's attention onto a focused task — confirming a delete, showing a form, or displaying extra details — without navigating away. Bootstrap's modal component handles the overlay, focus trapping, and open/close animation entirely through data attributes, with no custom JavaScript required for the basic case.
- The full modal markup structure.
- How to trigger a modal with data-bs-toggle and data-bs-target.
- Modal sizes, scrolling, and centering options.
- How to open/close modals from your own JavaScript.
Modal Structure
A modal is built from a nested set of divs: `.modal` (the outer wrapper, hidden by default), `.modal-dialog` (sizing/positioning), and `.modal-content` (the visible bordered box holding the actual content).
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <!-- header, body, footer go here --> </div> </div></div>Click Run to see what this code prints.
Triggering a Modal
A button opens the modal declaratively using `data-bs-toggle="modal"` and `data-bs-target="#modalId"`, matching the modal's `id`. No JavaScript is needed for this basic trigger — Bootstrap's bundled JS listens for the click automatically.
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal"> Open Modal</button>Click Run to see what this code prints.
Modal Header, Body & Footer
Inside `.modal-content`, use `.modal-header` for the title and close button, `.modal-body` for the main content, and `.modal-footer` for action buttons like Save/Cancel.
<div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Confirm Action</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <p>Are you sure you want to delete this course?</p> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button> <button type="button" class="btn btn-danger">Delete</button> </div></div>Click Run to see what this code prints.
Modal Sizes
Add `.modal-sm`, `.modal-lg`, or `.modal-xl` to `.modal-dialog` to control its width. Leaving the size class off gives you Bootstrap's default medium width.
<div class="modal-dialog modal-lg"> <div class="modal-content"><!-- ... --></div></div>Click Run to see what this code prints.
Scrollable & Centered Modals
`.modal-dialog-scrollable` keeps the header and footer fixed while only `.modal-body` scrolls internally when content is too tall for the viewport. `.modal-dialog-centered` vertically centers the whole dialog in the viewport instead of pinning it near the top.
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"> <div class="modal-content"><!-- long content --></div></div>Click Run to see what this code prints.
Static Backdrop & Keyboard Options
By default, clicking outside a modal or pressing Escape closes it. Set `data-bs-backdrop="static"` to prevent closing on an outside click (the modal will "shake" instead), and `data-bs-keyboard="false"` to disable the Escape key too — useful for forms that shouldn't be dismissed accidentally.
<div class="modal" id="forceModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1"> <!-- ... --></div>Click Run to see what this code prints.
Triggering Modals with JavaScript
When you need to open or close a modal programmatically (for example, after an async action succeeds), use Bootstrap's JavaScript Modal API instead of the data attributes.
const modalEl = document.getElementById('exampleModal');const modal = new bootstrap.Modal(modalEl);
modal.show();// later...modal.hide();Click Run to see what this code prints.
Common Mistakes
- Mismatched id and data-bs-target values, so the button click does nothing.
- Nesting one modal directly inside another, which Bootstrap explicitly does not support.
- Forgetting tabindex="-1" on the outer .modal element, hurting keyboard focus behavior.
- Putting position: fixed elements inside a modal body, which can behave unpredictably with the modal's own positioning.
Best Practices
- Use data-bs-backdrop="static" for forms or destructive confirmations that shouldn't close accidentally.
- Keep modal content focused on a single task — avoid stuffing entire pages into a modal.
- Always include a visible close button in addition to backdrop/Escape dismissal.
- Use modal-dialog-centered for short confirmation dialogs to keep them visually balanced.
- Reset form fields inside a modal when it closes, using the hidden.bs.modal event.
Frequently Asked Questions
Yes, as long as each modal has a unique id and its trigger uses the matching data-bs-target, but avoid opening one modal from within another.
Listen for the shown.bs.modal event on the modal element, which fires once the open animation completes.
No, Bootstrap locks body scrolling while a modal is open and restores it automatically when the modal closes.
Yes, use the JavaScript API (new bootstrap.Modal(el).show()) to open a modal from any event, such as a page load or a fetch callback.
Key Takeaways
- Modals nest .modal > .modal-dialog > .modal-content.
- Trigger buttons use data-bs-toggle="modal" and data-bs-target="#id" matching the modal.
- .modal-header, .modal-body, and .modal-footer structure the visible content.
- .modal-sm/.modal-lg/.modal-xl control width; modal-dialog-centered controls vertical position.
- data-bs-backdrop="static" and data-bs-keyboard="false" prevent accidental dismissal.
- The JavaScript Modal API (show()/hide()) lets you control modals outside of a click trigger.
Summary
Modals give you a clean way to interrupt the user's flow for a focused task, without the complexity of managing a separate page. With the header/body/footer structure and the data-bs-* trigger pattern, you can build confirmation dialogs, forms, and detail views entirely declaratively. Next, you'll learn dropdowns, another component built on the same data-bs-toggle pattern.