Bootstrap 5 Framework

Modals

14 min Lesson 31 of 40

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