Bootstrap modal with sticky header, footer, or both, and scrollable content (modern CSS solution)

There are many ways to achieve the sticky/fixed header and footer in the modal/dialog component. Let’s look into a pure CSS solution (without JavaScript). With the modern CSS, it’s very flexible, can be used with most of the modals from various frameworks, custom modal implementations, and, of course, with Bootstrap modal. Examples are based on Bootstrap 5, and I’ve tested it with Bootstrap versions from 3 to 5.

Modern CSS solution

Instead of relying on Flexbox or JavaScript, we can just use position: sticky. According to Can I use… it has pretty decent support and IMO can be used on production (depending on a use case). If a browser doesn’t support position: sticky, modal will work as usual, with static header and footer (a progressive enhancement approach).

The beauty of this solution is that it takes just a few lines of CSS, doesn’t require any JavaScript, and we don’t have to change the HTML markup.

Code example

Here is regular Bootstrap modal markup (taken from official docs):

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Launch demo modal
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="exampleModalLabel">Modal title</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
      </div>
      <div class="modal-body">
        ...
      </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>

To add sticky functionality we’ll use two separate BEM modifiers:

  • modal-header--sticky (header fixed top)
  • modal-footer--sticky (footer fixed bottom)

This way, we can easily enable or disable each element to make it sticky.

/* 
  1. Use the same color as modal.
  2. Ensure that the sticky layer is above the modal content.
*/

/* Header fixed to the top of the modal */
.modal-header--sticky {
  position: sticky;
  top: 0;
  background-color: inherit; /* [1] */
  z-index: 1055; /* [2] */
}

/* Footer fixed to the bottom of the modal */
.modal-footer--sticky {
  position: sticky;
  bottom: 0;
  background-color: inherit; /* [1] */
  z-index: 1055; /* [2] */
}

As you can see, it’s pretty simple, and can be used with any other modal solution.

Finally, let’s see the working example.

Live demo

Click the button below to see the example modal.

Sticky content within modal body

Using position: sticky with modal content and some additional CSS, we can take this idea even further.

Here is another example:

Sticky content within modal body.

Further reading

Share

Thanks for reading. If you liked it, consider sharing it with friends via:

Let's be in touch!

Don't miss other useful posts. Level up your skills with UX, web development, and productivity tips via e-mail.

Comments

If you want to comment, write a post on social media and @mention me or write to me directly on the contact page.