Modal

The modal component can be used to create dialogs, user notifications, lightboxes, or completely custom content.

Create amazing Typeform-like forms and pages just by writing Markdown!

Overview #

Modals are built with HTML, CSS, and JavaScript. They're positioned over everything else in the document and remove scroll from the <body> so that modal content scrolls instead. Here's a live example of a modal that can be opened by clicking on the button or the link. By default, clicking on the modal "backdrop" will automatically close the modal, but including a dedicated close button is recommended.

Open modal (it will slide down and fade in from the top)...

Launch modal
HTML
<!-- Modal toggles -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-1">
  Launch modal
</button>
<a href="#example-modal-1" role="button" class="btn btn-link" data-bs-toggle="modal">
  Launch modal
</a>

<!-- Modal -->
<div class="modal fade" id="example-modal-1" tabindex="-1" aria-labelledby="modal-title-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-1">Modal title</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        This is the modal body which can contain all types of custom content, such as forms, tooltips, popovers, grids, etc.
      </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</button>
      </div>
    </div>
  </div>
</div>

A few things to note about modals:

  • Modals use position: fixed, which can sometimes be a bit particular about its rendering. Whenever possible, place your modal HTML in a top-level position to avoid potential interference from other elements. You'll likely run into issues when nesting a .modal within another fixed element. This positioning may also cause some minor issues on mobile phones.
  • The modal content is made up of header (.modal-header), body (.modal-body) and footer (.modal-footer) components. The header and body are required for padding, but the footer is optional.
  • Modals can be toggled using data-bs-toggle="modal" on a button or link, though buttons are generally recommended for being the ideal choice. The targeting is done using data-bs-target for buttons, and href for links.

Accessibility #

Be sure to add aria-labelledby="...", referencing the modal title, to .modal. Additionally, you may give a description of your modal dialog with aria-describedby on .modal. Note that you don't need to add role="dialog" since we already add it via JavaScript.

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

Static backdrop #

When backdrop is set to static (e.g., using data-bs-static="true"), the modal will not close when clicking outside of it. Moreover, you can also disable esc key dismissal of modals (e.g., using data-bs-keyboard="false").

Open modal with static backdrop...

HTML
<!-- Modal toggle -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-2">
  Launch modal
</button>

<!-- Modal with static backdrop -->
<div class="modal fade" id="example-modal-2" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="modal-title-2" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-2">Modal title</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        This is the modal body which can contain all types of custom content, such as forms, tooltips, popovers, grids, etc.
      </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</button>
      </div>
    </div>
  </div>
</div>

Long scrolling content #

When modals become too long for the user's viewport or device, they scroll independent of the page itself. This is shown with the first modal in the example below. You can also create a scrollable modal that allows scrolling in the modal body by adding .modal-dialog-scrollable to .modal-dialog. This is shown with the second modal in the example below.

Open modals with long scrolling content...

HTML
<!-- Modal with long scrolling content (default body scrolling) -->
<div class="modal fade" id="example-modal-3" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

<!-- Modal with scrollable body -->
<div class="modal fade" id="example-modal-4" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-scrollable">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

Vertically centered #

Add .modal-dialog-centered to .modal-dialog to vertically center the modal. This will also work for modals with scrollable bodies with modal-dialog-scrollable.

Open vertically centered modal...

HTML
<!-- Vertically centered modal -->
<div class="modal fade" id="example-modal-5" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

Tooltips, popovers, and grid system #

Tooltips and popovers can be placed within modals as needed. When modals are closed, any tooltips and popovers within are also automatically dismissed. Moreover, you can also use the grid system within a modal by nesting .container-fluid within the .modal-body. Then, use the normal grid system classes as you would anywhere else.

Open modal with tooltip, popover, and grid...

HTML
<!-- Modal with tooltip, popover, and grid system -->
<div class="modal fade" id="example-modal-6" tabindex="-1" aria-labelledby="modal-title-6" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-6">Modal title</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <h5>Tooltip and popover</h5>
        <p class="mb-2">
          Here's <a href="#" data-bs-toggle="tooltip" data-bs-title="This is a tooltip">a link</a> with a tooltip inside the modal. You can also click on the following button to open a popover.
        </p>
        <div class="mb-4">
          <button type="button" class="btn btn-primary" data-bs-toggle="popover" data-bs-title="Title of the popover" data-bs-content="Content of the popover that spans across multiple lines.">
            Popover
          </button>
        </div>
        <h5>Grid system</h5>
        <p class="mb-2">
          And here's an example of the grid system.
        </p>
        <div class="container-fluid g-0">
          <div class="row">
            <div class="col-4">4</div>
            <div class="col-8">8</div>
          </div>
          <div class="row">
            <div class="col-sm-8 mt-3">sm-8</div>
            <div class="col-sm-4 mt-3">sm-4</div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

Forms and auto-focus #

You can also place forms inside modals. Please note, due to how HTML5 defines its semantics, the autofocus HTML attribute (opens in new tab) has no effect in modals. To achieve the same effect, use some custom JavaScript as shown in the example below.

Please sign in to continue...

HTML
<!-- Modal toggle -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-7">
  Sign in
</button>

<!-- Modal with form -->
<div class="modal fade" id="example-modal-7" tabindex="-1" aria-labelledby="modal-title-7" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-7">
          Sign in to your account
          <br />
          <small class="text-body-secondary fw-normal">Welcome back!</small>
        </h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="mb-3">
            <label for="email" class="form-label">Email address</label>
            <input type="email" class="form-control" id="email" placeholder="Email address">
          </div>
          <div class="mb-3">
            <label for="password" class="form-label">Password</label>
            <input type="password" class="form-control" id="password" placeholder="Password">
          </div>
          <div class="mb-3 pb-3 border-bottom">
            <button type="submit" class="btn btn-primary w-100">Sign in</button>
          </div>
          <div class="text-center text-body-secondary">
            Don't have an account? <a href="#">Sign up</a>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>
JavaScript
// Auto-focus when modal is opened
const signInModal = document.getElementById("example-modal-7");
const inputToFocus = document.getElementById("email");
if (signInModal) {
  signInModal.addEventListener("shown.bs.modal", () => {
    if (inputToFocus) {
      inputToFocus.focus();
    }
  });
}

Varying modal content #

Use event.relatedTarget and the data-bs-* attributes to vary the contents of the modal depending on which button was clicked to open it.

Open modal and send message to...

HTML
<!-- Modal toggles -->
<button type="button" class="btn btn-secondary" data-bs-toggle="modal" data-bs-target="#example-modal-8" data-bs-recipient="@steve">
  @steve
</button>
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-8" data-bs-recipient="@harrison">
  @harrison
</button>

<!-- Modal with form -->
<div class="modal fade" id="example-modal-8" tabindex="-1" aria-labelledby="modal-title-8" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-8">New message</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        <form>
          <div class="mb-3">
            <label for="recipient" class="form-label">Recipient</label>
            <input type="text" class="form-control" id="recipient" placeholder="Recipient">
          </div>
          <div class="mb-3">
            <label for="message" class="form-label">Message</label>
            <textarea class="form-control" id="message" rows="3" placeholder="Type your message"></textarea>
          </div>
          <div class="text-end pt-3 border-top">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Cancel</button>
            <button type="submit" class="btn btn-primary">Send message</button>
          </div>
        </form>
      </div>
    </div>
  </div>
</div>
JavaScript
// Vary modal content when opened
const sendMessageModal = document.getElementById("example-modal-8");
if (sendMessageModal) {
  sendMessageModal.addEventListener("show.bs.modal", (event) => {
    // Button that triggered the modal
    const button = event.relatedTarget;
    // Extract info from data-bs-* attributes
    const recipient = button.getAttribute("data-bs-recipient");
    // If necessary, you could initiate an Ajax request here
    // and then do the updating in a callback

    // Update the modal's content
    const modalTitle = sendMessageModal.querySelector(".modal-title");
    const modalInput = sendMessageModal.querySelector(".modal-body input");
    modalTitle.textContent = `New message to ${recipient}`;
    modalInput.value = recipient;
  });
}

Toggle between modals #

Toggle between multiple modals with some clever placement of the data-bs-target and data-bs-toggle attributes. For example, you could toggle a password reset modal from within an already open sign in modal. Please note multiple modals cannot be open at the same time—this method simply toggles between two separate modals.

Toggle between modals after opening the first one...

HTML
<!-- First modal toggle -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-9">
  Launch modal
</button>

<!-- First modal -->
<div class="modal fade" id="example-modal-9" tabindex="-1" aria-labelledby="modal-title-9" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-9">First modal</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        This is the body of the first modal. You can toggle to the second modal by clicking the button below. Multiple modals cannot be open at the same time!
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-10">Second modal</button>
      </div>
    </div>
  </div>
</div>

<!-- Second modal -->
<div class="modal fade" id="example-modal-10" tabindex="-1" aria-labelledby="modal-title-10" aria-hidden="true">
  <div class="modal-dialog modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header">
        <h1 class="modal-title fs-5" id="modal-title-10">Second modal</h1>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        This is the body of the second modal. You can go back to the first modal by clicking the button below. Multiple modals cannot be open at the same time!
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#example-modal-9">First modal</button>
      </div>
    </div>
  </div>
</div>

Remove animation #

For modals that simply appear rather than fade in to view, remove the .fade class from your modal markup.

Dynamic heights #

If the height of a modal changes while it is open, you should call myModal.handleUpdate() to readjust the modal's position in case a scrollbar appears.

Optional sizes #

Modals have three optional sizes, available via modifier classes to be placed on a .modal-dialog. These sizes kick in at certain breakpoints to avoid horizontal scrollbars on narrower viewports. Our default modal without modifier class constitutes the "medium" size modal.

Size Class Max-width
Default .modal-dialog 500px
Small .modal-dialog and .modal-sm 300px
Large .modal-dialog and .modal-lg 800px
Extra large .modal-dialog and .modal-xl 1140px

Open modal with optional sizes...

HTML
<!-- Small modal -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-sm">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

<!-- Large modal -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

<!-- Extra large modal -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-xl">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

Fullscreen modals #

Another override is the option to pop up a modal that covers the user viewport, available via modifier classes that are placed on a .modal-dialog.

Class Availability
.modal-fullscreen Always
.modal-fullscreen-sm-down Screens up to 576px
.modal-fullscreen-md-down Screens up to 768px
.modal-fullscreen-lg-down Screens up to 992px
.modal-fullscreen-xl-down Screens up to 1200px
.modal-fullscreen-xxl-down Screens up to 1400px

Open fullscreen modals (including responsive variation)...

HTML
<!-- Fullscreen modal -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-fullscreen">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

<!-- Responsive fullscreen modal -->
<div class="modal fade" tabindex="-1" aria-hidden="true">
  <div class="modal-dialog modal-fullscreen-sm-down">
    <div class="modal-content">
      ...
    </div>
  </div>
</div>

JavaScript usage #

The examples on this page use data-bs-* attributes for functionality, which is usually enough to cover a majority of use-cases. You can read about options, methods, events, and more in the official Bootstrap documentation.

Modal - Bootstrap
Continue reading on the offical documentation website

Up next
Navbar

Help us grow

Our main goal is to make Halfmoon the go-to framework for building websites, dashboards and tools. If you believe in our mission, consider becoming a sponsor and help us grow.

You can email us directly if you have any queries. We are always happy to answer.

Subscribe for updates

We will notify you when the framework gets a substantial update. No spam ever.

Follow us on Twitter so that you can stay updated that way.