Modals in Bootstrap 5
Modals are dialog boxes/popups that overlay the page. Bootstrap 5 modals are responsive, customizable, and provide a clean way to display content without navigating away from the current page.
Basic Modal Structure
A modal consists of three main parts: header, body, and footer.
<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#basicModal">
Launch Demo Modal
</button>
<!-- Modal -->
<div class="modal fade" id="basicModal" tabindex="-1" aria-labelledby="basicModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="basicModalLabel">Modal Title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>This is the modal body content. You can put any content here!</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
<button type="button" class="btn btn-primary">Save Changes</button>
</div>
</div>
</div>
</div>
Important: The fade class adds animation, data-bs-toggle="modal" triggers the modal, and data-bs-target points to the modal's ID.
Modal Sizes
Bootstrap provides different modal sizes using modifier classes on .modal-dialog.
<!-- Small Modal -->
<div class="modal-dialog modal-sm">
<div class="modal-content">
<!-- Content -->
</div>
</div>
<!-- Default/Medium Modal (no class needed) -->
<div class="modal-dialog">
<div class="modal-content">
<!-- Content -->
</div>
</div>
<!-- Large Modal -->
<div class="modal-dialog modal-lg">
<div class="modal-content">
<!-- Content -->
</div>
</div>
<!-- Extra Large Modal -->
<div class="modal-dialog modal-xl">
<div class="modal-content">
<!-- Content -->
</div>
</div>
Fullscreen Modals
Bootstrap 5 introduced fullscreen modals that cover the entire viewport.
<!-- Always Fullscreen -->
<div class="modal-dialog modal-fullscreen">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Fullscreen Modal</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>This modal takes up the entire screen!</p>
</div>
</div>
</div>
<!-- Fullscreen below specific breakpoint -->
<div class="modal-dialog modal-fullscreen-sm-down"><!-- Fullscreen on small screens --></div>
<div class="modal-dialog modal-fullscreen-md-down"><!-- Fullscreen on medium and below --></div>
<div class="modal-dialog modal-fullscreen-lg-down"><!-- Fullscreen on large and below --></div>
<div class="modal-dialog modal-fullscreen-xl-down"><!-- Fullscreen on XL and below --></div>
<div class="modal-dialog modal-fullscreen-xxl-down"><!-- Fullscreen on XXL and below --></div>
Responsive Tip: Use modal-fullscreen-{breakpoint}-down to make modals fullscreen only on smaller devices while keeping them as dialogs on larger screens.
Vertically Centered Modal
Center the modal vertically in the viewport using .modal-dialog-centered.
<div class="modal fade" id="centeredModal" tabindex="-1">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Vertically Centered</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>This modal is vertically centered in the viewport.</p>
</div>
</div>
</div>
</div>
<!-- Centered and Scrollable -->
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable">
<!-- Content -->
</div>
Scrollable Modal Body
Make the modal body scrollable when content is too long using .modal-dialog-scrollable.
<div class="modal fade" id="scrollableModal" tabindex="-1">
<div class="modal-dialog modal-dialog-scrollable">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Scrollable Modal</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>Long content here...</p>
<p>This content will scroll inside the modal body.</p>
<!-- More content -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
Modal with Forms
Modals are commonly used for forms and data input.
<div class="modal fade" id="formModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Sign Up</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<form>
<div class="mb-3">
<label for="userName" class="form-label">Name</label>
<input type="text" class="form-control" id="userName" required>
</div>
<div class="mb-3">
<label for="userEmail" class="form-label">Email address</label>
<input type="email" class="form-control" id="userEmail" required>
</div>
<div class="mb-3">
<label for="userPassword" class="form-label">Password</label>
<input type="password" class="form-control" id="userPassword" required>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="agreeTerms">
<label class="form-check-label" for="agreeTerms">
I agree to the terms and conditions
</label>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-primary">Create Account</button>
</div>
</div>
</div>
</div>
Multiple Modal Triggers
Different buttons can trigger the same modal.
<!-- Multiple triggers -->
<button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#sharedModal">
Open from Button 1
</button>
<a href="#" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#sharedModal">
Open from Link
</a>
<button class="btn btn-warning" data-bs-toggle="modal" data-bs-target="#sharedModal">
Open from Button 2
</button>
<!-- Shared Modal -->
<div class="modal fade" id="sharedModal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">Shared Modal</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal"></button>
</div>
<div class="modal-body">
<p>This modal can be opened from multiple triggers.</p>
</div>
</div>
</div>
</div>
Modal Options and JavaScript
Control modals programmatically with JavaScript.
<script>
// Get modal element
const myModalEl = document.getElementById('myModal');
// Create modal instance
const modal = new bootstrap.Modal(myModalEl, {
keyboard: false, // Disable closing with ESC key
backdrop: 'static' // Disable closing by clicking backdrop
});
// Show modal
modal.show();
// Hide modal
modal.hide();
// Toggle modal
modal.toggle();
// Event listeners
myModalEl.addEventListener('show.bs.modal', function (event) {
console.log('Modal is about to be shown');
});
myModalEl.addEventListener('shown.bs.modal', function (event) {
console.log('Modal is fully shown');
});
myModalEl.addEventListener('hide.bs.modal', function (event) {
console.log('Modal is about to be hidden');
});
myModalEl.addEventListener('hidden.bs.modal', function (event) {
console.log('Modal is fully hidden');
});
</script>
Practice Exercise
Task: Create a complete user profile modal with the following features:
- Large size modal
- Vertically centered
- Form with: profile picture upload, name, email, bio (textarea), and social links
- Separate sections for personal info and social media
- Save and Cancel buttons in footer
- Add JavaScript to show an alert when Save is clicked
Bonus Challenge: Create two modals - one for editing profile and another for confirming deletion. Add a "Delete Account" button in the first modal that opens the confirmation modal.
Best Practices
- Always include
aria-labelledby and aria-hidden for accessibility
- Use appropriate modal sizes based on content amount
- Provide clear close buttons (X button and Cancel button)
- Use
modal-dialog-scrollable for long content instead of making the entire page scroll
- Don't nest modals (opening a modal inside another modal)
- Test keyboard navigation (Tab, Esc, Enter keys)
- Use
backdrop: 'static' for important actions that shouldn't be accidentally dismissed