Multiple modals overlay
Solution 1
Solution inspired by the answers of @YermoLamers & @Ketwaroo.
Backdrop z-index fix
This solution uses a setTimeout
because the .modal-backdrop
isn't created when the event show.bs.modal
is triggered.
$(document).on('show.bs.modal', '.modal', function() {
const zIndex = 1040 + 10 * $('.modal:visible').length;
$(this).css('z-index', zIndex);
setTimeout(() => $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack'));
});
- This works for every
.modal
created on the page (even dynamic modals) - The backdrop instantly overlays the previous modal
Example jsfiddle
z-index
If you don't like the hardcoded z-index for any reason you can calculate the highest z-index on the page like this:
const zIndex = 10 +
Math.max(...Array.from(document.querySelectorAll('*')).map((el) => +el.style.zIndex));
Scrollbar fix
If you have a modal on your page that exceeds the browser height, then you can't scroll in it when closing an second modal. To fix this add:
$(document).on('hidden.bs.modal', '.modal',
() => $('.modal:visible').length && $(document.body).addClass('modal-open'));
Versions
This solution is tested with bootstrap 3.1.0 - 3.3.5
Solution 2
I realize an answer has been accepted, but I strongly suggest not hacking bootstrap to fix this.
You can pretty easily achieve the same effect by hooking the shown.bs.modal and hidden.bs.modal event handlers and adjusting the z-index there.
A bit more info is available here.
This solution works automatically with arbitrarily deeply stacks modals.
The script source code:
$(document).ready(function() {
$('.modal').on('hidden.bs.modal', function(event) {
$(this).removeClass( 'fv-modal-stack' );
$('body').data( 'fv_open_modals', $('body').data( 'fv_open_modals' ) - 1 );
});
$('.modal').on('shown.bs.modal', function (event) {
// keep track of the number of open modals
if ( typeof( $('body').data( 'fv_open_modals' ) ) == 'undefined' ) {
$('body').data( 'fv_open_modals', 0 );
}
// if the z-index of this modal has been set, ignore.
if ($(this).hasClass('fv-modal-stack')) {
return;
}
$(this).addClass('fv-modal-stack');
$('body').data('fv_open_modals', $('body').data('fv_open_modals' ) + 1 );
$(this).css('z-index', 1040 + (10 * $('body').data('fv_open_modals' )));
$('.modal-backdrop').not('.fv-modal-stack').css('z-index', 1039 + (10 * $('body').data('fv_open_modals')));
$('.modal-backdrop').not('fv-modal-stack').addClass('fv-modal-stack');
});
});
Solution 3
Combining A1rPun's answer with the suggestion by StriplingWarrior, I came up with this:
$(document).on({
'show.bs.modal': function () {
var zIndex = 1040 + (10 * $('.modal:visible').length);
$(this).css('z-index', zIndex);
setTimeout(function() {
$('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
}, 0);
},
'hidden.bs.modal': function() {
if ($('.modal:visible').length > 0) {
// restore the modal-open class to the body element, so that scrolling works
// properly after de-stacking a modal.
setTimeout(function() {
$(document.body).addClass('modal-open');
}, 0);
}
}
}, '.modal');
Works even for dynamic modals added after the fact, and removes the second-scrollbar issue. The most notable thing that I found this useful for was integrating forms inside modals with validation feedback from Bootbox alerts, since those use dynamic modals and thus require you to bind the event to document rather than to .modal, since that only attaches it to existing modals.
Solution 4
Something shorter version based off Yermo Lamers' suggestion, this seems to work alright. Even with basic animations like fade in/out and even crazy batman newspaper rotate. http://jsfiddle.net/ketwaroo/mXy3E/
$('.modal').on('show.bs.modal', function(event) {
var idx = $('.modal:visible').length;
$(this).css('z-index', 1040 + (10 * idx));
});
$('.modal').on('shown.bs.modal', function(event) {
var idx = ($('.modal:visible').length) -1; // raise backdrop after animation.
$('.modal-backdrop').not('.stacked').css('z-index', 1039 + (10 * idx));
$('.modal-backdrop').not('.stacked').addClass('stacked');
});
Solution 5
A simple solution for Bootstrap 4.5
.modal.fade {
background: rgba(0, 0, 0, 0.5);
}
.modal-backdrop.fade {
opacity: 0;
}
Related videos on Youtube
Willian Bonho Daiprai
Updated on July 08, 2022Comments
-
Willian Bonho Daiprai almost 2 years
I need that the overlay shows above the first modal, not in the back.
$('#openBtn').click(function(){ $('#myModal').modal({show:true}) });
<a data-toggle="modal" href="#myModal" class="btn btn-primary">Launch modal</a> <div class="modal" id="myModal"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title">Modal title</h4> </div><div class="container"></div> <div class="modal-body"> Content for the dialog / modal goes here. <br> <br> <br> <br> <br> <a data-toggle="modal" href="#myModal2" class="btn btn-primary">Launch modal</a> </div> <div class="modal-footer"> <a href="#" data-dismiss="modal" class="btn">Close</a> <a href="#" class="btn btn-primary">Save changes</a> </div> </div> </div> </div> <div class="modal" id="myModal2" data-backdrop="static"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button> <h4 class="modal-title">Second Modal title</h4> </div><div class="container"></div> <div class="modal-body"> Content for the dialog / modal goes here. </div> <div class="modal-footer"> <a href="#" data-dismiss="modal" class="btn">Close</a> <a href="#" class="btn btn-primary">Save changes</a> </div> </div> </div> </div> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/js/bootstrap.min.js"></script>
I tried to change the
z-index
of.modal-backdrop
, but it becomes a mess.In some cases I have more than two modals on the same page.
-
Zim about 3 yearsThe question specifically relates to multiple modal backdrop overlays. For other "open multiple modals in Bootstrap" see: stackoverflow.com/questions/19528173/…
-
Billu about 2 years
-
-
Willian Bonho Daiprai over 10 yearsOk, that's great, but I put a third modal and it not works. I have some scripts that generate it (like alerts, search boxes, etc) and I can have 3 opened modals at once (until i know). I'm not good with css, sorry if i loose something. There is the code: bootply.com/86975
-
Somnium almost 10 yearsCool, however when one modal is closed, there appears two scrollbars -one for modal, second for whole page. Can be this solved?
-
Yermo Lamers almost 10 yearsAre you using the latest bootstrap?
-
Somnium almost 10 yearsYes, you can see this in that example too if you download it and add a lot of text inside page.
-
StriplingWarrior over 9 yearsOne problem that remains here is that if you close out the second modal and your page has enough text to exceed the browser size, you end up with weird scrollbar behavior. You have to also restore the
modal-open
class on the body element: jsfiddle.net/vkyjocyn -
Lee over 9 yearsTo deal with the extra scoll bar on close, you need to add class "modal-open" to the body in the hidden.bs.modal listener.
-
ScubaSteve over 9 yearsOne issue I ran into was when the first modal was showing and needed a scrollbar, if I showed a second modal, it would remove the first modal's scrollbar and I was stuck with a clipped modal. To solve this, I just added this to my CSS, .modal { overflow-y: auto; }
-
harco gijsbers over 9 yearsMay i suggest using the max z index of the open modals to determine the base z-index instead of the hardcoded value of 1040 ? stackoverflow.com/a/5680815/2569159
-
A1rPun about 8 yearsNice solution. I expect the backdrop to go darker when you have multiple modals but I can see why you wouldn't want it. @AndyBurton Can you please let me know what my solution is missing?
-
Andy Burton about 8 years@A1rPun upon opening and closing the 2nd modal the scroll bars which allowed scrolling in the 1st modal were removed. IIRC this looked to be because the class on the body was removed when the 2nd modal was closed.
-
A1rPun about 8 years@AndyBurton I handle the solution to that problem as well.
-
Vishal over 7 years@A1rPun not working for me.. when i close the second modal.. the body become scrollable.. i used all your code.. :(
-
metamagikum over 7 yearsNot worked in my environment with latest bs. I had to do: $('.modal-backdrop').last().not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
-
FluffyKitten over 6 yearsCode-only answers are often unhelpful in pointing to why the issue happened. You should include an explanation why it solves the issue. Please read How do I write a good answer?
-
benrwb about 6 yearsI had to make a minor change (added
.not(this)
to the second line) to get it working with bootstrap datepickervar zIndex = 1040 + (10 * $('.modal:visible').not(this).length);
-
Diego Jancic about 6 yearsWorks well. I had to change the way it attaches to events to this form
$(document).on('---event---', '.modal', function() ...
instead of$('.modal').on('---event---', ...)
because the content was rendered after the document ready event. -
Matthew Goheen over 5 yearsI feel like this should be the accepted answer. Works flawlessly for me.
-
sanjeev shetty over 4 yearsI Loved it. Addon to this,
$('.modal:visible').length && $(document.body).addClass('modal-open');
inhidden.bs.modal
function -
Murphybro2 about 4 yearsIf two modals exist, then the first is removed and a third is added, the third will have the same z-index as the second as they both used a length of 2. I needed to factor in the last used z-index across the modals.
-
wobsoriano about 4 yearsWorks fine with BS4 latest
-
Ben in CA almost 4 yearsThis seems to work good... you'd think this would be standard Bootstrap?
-
Captain Squirrel almost 4 yearsWorked perfectly for me
-
Matt Drouillard over 3 yearsYou're a genius, this is incredible; if I could buy you a beer I would; Cheers.
-
kite over 3 yearsI combined your css with javascript fixes for bootstrap multiple modal not scrolling issue github.com/nakupanda/bootstrap3-dialog/issues/…, the stackOverflow issue: stackoverflow.com/a/64662694/423356
-
Ugo over 3 yearsWorked for me, but I also got a second scroll bar appearing.
-
Nalin Jayasuriya about 3 yearsThis solution works for Bootstrap 5 as well. Thank you Ricardo!
-
Gorelov Grigory almost 3 yearsBesto solution for me using BS5.
-
ɐsɹǝʌ ǝɔıʌ over 2 yearsSuperb! Works like a charm.
-
Tahir Alvi over 2 yearsWorks fine with bs4 in Dec 2021 even. Thanks @A1rPun
-
Mu-Tsun Tsai over 2 yearsWow this is crazy simple! Bootstrap team really should just use this!
-
Nicholas about 2 yearsYou just saved me (Vuejs, bootstrap5, nested modals)
-
Jorge Wander Santana Ureña almost 2 yearsconsidere adding ``
-
A1rPun almost 2 years@JorgeWanderSantanaUreña I'm not sure what you mean, I'm not doing any interpolation.
-
Jorge Wander Santana Ureña almost 2 yearsmy bad, ignore my comment.
-
nfplee almost 2 yearsThis no longer works as of Bootstap 5.1. See github.com/twbs/bootstrap/issues/34982 for more information.