Scrolling issues with multiple bootstrap modals
Asked Answered
A

8

54

I have a page with a modal with a lot of info so you need to scroll. This modal contains a link to a second modal.

When I

  • open modal 1
  • click on link to open modal 2 (modal 1 stays in background)
  • and then close modal 2 so that I am back on modal 1

modal 1 looses scrolling (there is still a scroll bar but it doesn't do anything). Instead the modal stays in the position it was at the time of opening modal 2.

I played around with closing the background modal with js first (but that messes up scrolling on the second modal). It appears that every time I try to open/close more than one modal I always get some issue with the scrolling.

Any suggestions on how to handle this?

Aleen answered 6/4, 2016 at 19:23 Comment(2)
Please share the codeBiltong
Recreated the issue with this fiddle.Trial
T
73

Add

.modal { overflow: auto !important; }

To your CSS.

Without your code I went ahead and created this jsFiddle that recreates your issue, or at least a very similar one. Add your code and I will test if this works or not.

Adding that line to the CSS fixed the issue as demonstrated with this jsFiddle.

Solution taken from this thread on github which offers other solutions as well.

Trial answered 6/4, 2016 at 19:45 Comment(5)
This fixed it! The only, somewhat minor issue with it appears to be that after you close the second modal, a second scroll bar becomes visible (seems to be from the main page). (Unfortunately the code is too big to post here...)Aleen
The solutions provided by Ahsan Khan / Abir.d don't have the second scroll bar bug.Nigro
Perfect solution, simply and effective. Thanks.Baleful
Can someone explain though why the problem exists in the first place? Ie why does the first modal lose scrollability?Uptown
this is not the right solution. Not it shows two scrolls.. one for the modal and another for the background content.Peritoneum
R
41

The solution that worked for me was:

$('.modal').on("hidden.bs.modal", function (e) { 
    if ($('.modal:visible').length) { 
        $('body').addClass('modal-open');
    }
});
Rink answered 25/10, 2017 at 12:49 Comment(3)
Better to use 'body' selector isntead of '.modal' because modals usually dynamically created. In this case this code snippet can be executed once on start and all modals should be fine then.Climate
Solution apported by @ahsan-khan (https://mcmap.net/q/119002/-scrolling-issues-with-multiple-bootstrap-modals) is better because also works for dynamically generated modals.Mimimimic
kpull1 this solution avoids the bug where the page's scrollbar shows as a second scrollbar as with ahsan-khan's solution.Nigro
C
33
   $(document).on('hidden.bs.modal', '.modal', function () {
        $('.modal:visible').length && $(document.body).addClass('modal-open');
   });
Charcuterie answered 14/3, 2019 at 12:42 Comment(5)
it's better to explain why this snippet solves the problemSefton
basically default bootstrap modal depends on "modal-open" class in the html body element (when a modal is opened). If we use multiple BS modal using ajax, we can mess with removing "modal-open" class when there are other visible modal need to use the selector. So need to track visible modal; only remove the "modal-open" when there is no visible one. This github link also handle backdrop z-index github.com/nakupanda/bootstrap3-dialog/issues/… If we only fix the css without tracking visible modal with js. the layer below modal is scrollable, not good for mobilePatch
I use ajax loading spinner using bootstrap modal globally for all ajax request, so $('.modal:visible').length is not accurate, I have to use global counter to count/track opened modal. and add the 'modal-open' class to body if the opened modal counter is not 0Patch
This is better answer :)Fluoride
Or bind that event in the modal initialization to the modal that is stacked over others. Might be less intrusive.Jerboa
C
8

this is the solution:

<script>
    $('#id_ofyou_secondary_modal').on('hidden.bs.modal', function (e) {

      $('body').addClass('modal-open');

    });
</script>

take care that "#idofyousecondarymodal" is the id of the secondary or tertiary or infinite modal. but NEVER write the ID of the first modal.

example i have 2 modal:

<div id="mymodal1" class="modal fade in" style="display:none;">
.
.
.
.
</div>
<div id="mymodal2" class="modal fade in" style="display:none;">
.
.
.
.
</div>   

then the script will be:

<script>
    $('#mymodal2').on('hidden.bs.modal', function (e) {

      $('body').addClass('modal-open');

    });
</script>

jus add this code and work fine.

Cryolite answered 22/6, 2017 at 18:26 Comment(0)
P
5

I tried the previous solutions, and not working for my use case:

  1. just adding css .modal { overflow: auto !important; } This will cause the content below modal become scrollable. Not good when you want to keep the previous content position. especially in mobile browser.
  2. Use javascript to track opened modal and keep the 'modal-open' class in body element using this jQuery selector $('.modal:visible').length. This is not working when there are multiple modal opened and closed fast. I use BS modal for my ajax spinner, so the $('.modal:visible') is not accurate.

This is the working one for me:

  1. Use JS global variable to keep track/count of opened modal; instead of just using :visible selector
  2. And I added css style so I don't have to recalculate backdrop z-index https://mcmap.net/q/116198/-multiple-modals-overlay

var bootstrapModalCounter = 0; //counter is better then using visible selector

    $(document).ready(function () {  
      $('.modal').on("hidden.bs.modal", function (e) {
        --bootstrapModalCounter;
        if (bootstrapModalCounter > 0) {
          //don't need to recalculate backdrop z-index; already handled by css
          //$('.modal-backdrop').first().css('z-index', parseInt($('.modal:visible').last().css('z-index')) - 10);
          $('body').addClass('modal-open');
        }
      }).on("show.bs.modal", function (e) {
        ++bootstrapModalCounter;
        //don't need to recalculate backdrop z-index; already handled by css
      });
    });
.modal { 
/*simple fix for multiple bootstrap modal backdrop issue: 
don't need to recalculate backdrop z-index;
https://mcmap.net/q/116198/-multiple-modals-overlay/21816777 */
  background: rgba(0, 0, 0, 0.5);
}

This is modified fiddle from @Keeleon for the fix https://jsfiddle.net/4m68uys7/

This is github issue https://github.com/nakupanda/bootstrap3-dialog/issues/70

Patch answered 3/11, 2020 at 12:17 Comment(0)
T
2

Add following to your CSS :

.modal
{
  overflow: scroll !important;
}
Talley answered 15/11, 2017 at 6:47 Comment(0)
P
0

The only think that worked for me is this:

$('#searchModal').on('hidden.bs.modal', function (e) {
    var scrollPosition = window.scrollY || document.documentElement.scrollTop;
    setTimeout(() => {
            window.scrollTo(0, scrollPosition);
    }, 1);
}); 
   
Peewee answered 14/11, 2023 at 22:53 Comment(0)
K
0

Simple code: Craete plugin Jquery to fixed the scroll and backdrop issue

(function ($)
{
    $.fn.myModal = function (method)
    {
        let modalIndex = 1050; //default index
        let backdropIndex = 1040;//default index
        $(this).modal(method);

        $(this).on("hidden.bs.modal", function (e)
        {
            if ($('.modal:visible').length)
            {
                //keep scroll parent modal
                $('body').addClass('modal-open');
            }
        });

        $(this).on("shown.bs.modal", function (e)
        {
            let modals = $('.modal:visible');
            let backdrops = $('.modal-backdrop:visible');
            if (backdrops.length <= 1)
            {
                return;
            }              

            for (let i = 1; i < backdrops.length; i++)
            {
                $(backdrops[i]).css({ 'z-index': modalIndex + 10 * i });
                $(modals[i]).css({ 'z-index': modalIndex + 10 * i + 1 });
            }
        });
        return this;
    };
}(jQuery));

Use this code

$('#modal-id').myModal('toggle');
Krems answered 27/1, 2024 at 8:6 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.