Bootstrap Modal sitting behind backdrop
Asked Answered
C

32

78

So I'm having nearly the exact same problem as @Jamescoo was but I think that my issue is coming from the fact that I have already positioned a couple of DIVs to create a sliding nav panel.

Here's my exact setup replicated: http://jsfiddle.net/ZBQ8U/2/

BONUS: Feel free to grab the code for the sliding panel if you'd like :)

The z-indexes shouldn't conflict and their values would show that they are stacking correctly, but visually they are not.

Once you click the 'Open Modal' button the <div class="modal-backdrop fade in"></div> covers everything! (you'll have to re-run the code to reset it)

I don't know quite how to remedy this one...Any ideas?

Charmeuse answered 7/1, 2014 at 22:17 Comment(3)
This seems to be the same issue as here; see that accepted answer for a more in-depth discussion.Mccalla
@TobyJ 's provided link has the answer, but not the "accepted" one ;) The answer by Adam Albright is the one that works best, without any complications. That is, if you're using jQuery.Jiffy
Check this I've updated your jsfiddle jsfiddle.net/ZBQ8U/513Changeless
C
139

Just move the entire modal outside of the rest of your code, to the very bottom. It doesn't need to be nested in any other element, other than the body.

<body>
    <!-- All other HTML -->
    <div>
        ...
    </div>

    <!-- Modal -->
    <div class="modal fade" id="myModal">
        ...
    </div>
</body>

Demo

They hint at this solution in the documentation.

Modal Markup Placement
Always try to place a modal's HTML code in a top-level position in your document to avoid other components affecting the modal's appearance and/or functionality.

Clichy answered 7/1, 2014 at 22:56 Comment(4)
Thank you! Moving the modal as suggested did the trick perfectly! Everyone, be sure to read below @davidpauljunior's in-depth explanation as to why the .modal-backdrop was covering everything up!!Charmeuse
I wrote my code like this and yet it's still happening. :/Rozele
That was actually the solution to my problem. My div was within the form of Struts.Baseline
@KehlanKrumme this is not the fault of Bootstrap. Understanding "stacking context" is necessary to solve this problem. Good reading: philipwalton.com/articles/what-no-one-told-you-about-z-indexJustinajustine
C
34

In my case, I could fix it by adding css for the .modal-backdrop

.modal-backdrop {
  z-index: -1;
}

Although this works, form controls still seem to appear above the backdrop, clicking anywhere dismisses the modal, but it doesn't look great.

A better workaround for me is to bind to the shown event (once the page is loaded) and to correct the z-index property.

$('.modal').on('shown.bs.modal', function() {
  $(this).css("z-index", parseInt($('.modal-backdrop').css('z-index')) + 1);
});

In this case, if you are OK with changing the DOM on modal shown:

$('.modal').on('shown.bs.modal', function() {
  //Make sure the modal and backdrop are siblings (changes the DOM)
  $(this).before($('.modal-backdrop'));
  //Make sure the z-index is higher than the backdrop
  $(this).css("z-index", parseInt($('.modal-backdrop').css('z-index')) + 1);
});
Cerys answered 3/3, 2015 at 6:52 Comment(3)
The only solution that worked in my case! Thank you. by the way, the CSS part was enough for meMarigolde
z-index: -1; made some page elements to overlay the backdrop. $(this).before($('.modal-backdrop')); worked better, but when you scroll down, the page elements start to appear. The solution was to move the modal window out of the body. See my reply.Blaylock
Wow thank you so much! :) The third code block snippet is what worked for me :)Goon
P
30

Although the z-index of the .modal is higher than that of the .modal-backdrop, that .modal is in a parent div #content-wrap which has a lower z-index than .modal-backdrop (z-index: 1002 vs z-index: 1030).

Because the parent has lower z-index than the .modal-backdrop everything in it will be behind the modal, irrespective of any z-index given to the children.

If you remove the z-index you have set on both the body div#fullContainer #content-wrap and also on the #ctrlNavPanel, everything seems to work ok.

body div#fullContainer #content-wrap {
  background: #ffffff;
  bottom: 0;
  box-shadow: -5px 0px 8px #000000;
  position: absolute;
  top: 0;
  width: 100%;
}

#ctrlNavPanel {
  background: #333333;
  bottom: 0;
  box-sizing: content-box;
  height: 100%;
  overflow-y: auto;
  position: absolute;
  top: 0;
  width: 250px;
}

NOTE: I think that you may have initially used z-indexes on the #content-wrap and #ctrlNavPanel to ensure the nav sits behind, but that's not necessary because the nav element comes before the content-wrap in the HTML, so you only need to position them, not explicitly set a stacking order.


EDIT As Schmalzy picked up on, the links are no longer clickable. This is because the full-container is 100% wide and so covers the navigation. The quickest way to fix this is to place the navigation inside that div:

<div id="fullContainer">
  <aside id="ctrlNavPanel">
    <ul class="nav-link-list">
      <li><label>Menu</label></li>
      <li><a href="/"><span class="fa fa-lg fa-home"></span> Home</a></li>
      <li><a><span class="fa fa-lg fa-group"></span>About Us</a></li>
      <li><a><span class="fa fa-lg fa-book"></span> Contacts</a></li>
    </ul>
  </aside>
  <div id="content-wrap">
    ...
  </div>
</div>

DEMO HERE

Postglacial answered 7/1, 2014 at 22:41 Comment(4)
Can whoever downvoted provide an explanation as to why this is incorrect?Postglacial
Sorry, I was getting to that.. Removing the z-index seems to break his #ctrlNavPanel. Links no longer work.Clichy
Ah yes well spotted! Have added in an HTML edit fix for that. ThanksPostglacial
@Postglacial Great in-depth explanation! Thank you so much for the quick response!! This will be very helpful for others struggling with z-indexing as I was with in this scenario. I've gotta give the nod to @Clichy though for catching the #ctrlNavPanel break and the simplicity of suggesting to just move the modal to the bottom of the code just before the closing body tag </body>.Charmeuse
B
17

None of the answers worked well enough for me. The problem appeared to lie where the modal windows needs to be outside of the body.and it is not best

So this code done the job just prefectly:

$('.modal ').insertAfter($('body'));
$('#product_' + product_id + ' .modal ').insertAfter($('body'));
Blaylock answered 3/1, 2016 at 23:37 Comment(2)
Same for me. The solutions with the index worked only "haflish". There where still elements hidden behind the backdrop. This solution with moving the modal outside the body worked perfectly. Thanks!Outpour
This makes inputs in the modal not working on IE11 (and maybe other versions). DO NOT USE this solution, if you have inputs inside modal.Manzanilla
D
16

I'm wary of moving the modal content outside its original context: other JS or styles might depend on that context.

However, I doubt there are any scripts or styles that require a specific context for the backdrop.

So my solution is to move the backdrop adjacent to the modal content, forcing it into the same stacking context:

$(document).on('shown.bs.modal', '.modal', function () {
    $('.modal-backdrop').before($(this));
});

It's only a slight deviation from jacoswarts' solution, so thanks for the inspiration!

Dickson answered 11/10, 2018 at 19:21 Comment(2)
Thanks for that man, you saved me a lot of time! I was already searching this for a couple of hours...Bithia
@Bithia I remember this issue like it was yesterday. Glad to help! :-)Dickson
I
7

Try remove the backdrop, if you don't realy need it (data-backdrop= "false"):

<div class="modal fade" data-backdrop="false" role="dialog" id="my-modal" aria-labelledby="modal-title">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h3 class="modal-title" id="modal-title">No Backdrop</h3>
                </div>
                <div class="modal-body">
                    <p>
                        Look! No backdrop here!
                    </p>
                </div>
                <div class="modal-footer">
                    <button class="btn btn-default" data-dismiss="modal">Cancel</button>
                    <button class="btn btn-primary">Ok</button>                    </div>
            </div>
        </div>
    </div>
Inebriant answered 18/3, 2016 at 14:47 Comment(0)
A
6

I know it is late, I encountered the same problem but I had to hack it out as below;

 .modal-backdrop {
      /* bug fix - no overlay */    
      display: none;    
}

.modal{
    /* bug fix - custom overlay */   
    background-color: rgba(10,10,10,0.45);
}
Allonym answered 1/2, 2021 at 6:1 Comment(1)
Works great, fixed my issueCrenulation
S
5

I was fighting with the same problem some days... I found three posible solutions, but i dont know, which is the most optimal, if somebody tell me, i will be grateful.

the modifications will be in bootstrap.css

Option 1:

.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: 1040; <- DELETE THIS LINE
  background-color: #000000;
}

Option 2:

.modal-backdrop {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -1; <- MODIFY THIS VALUE BY -1
  background-color: #000000;
}

Option 3:

/*ADD THIS*/
.modal-backdrop.fade.in {
    z-index: -1;
}

I used the option 2.

Spitler answered 29/9, 2015 at 13:54 Comment(1)
z-index: 1; worked for meEpps
A
4

In my case one of parents of my modal was animated and had this

.animated {
    -webkit-animation-duration: 1s;
    animation-duration: 1s;
    -webkit-animation-fill-mode: both;
    animation-fill-mode: both;
    z-index: 100;
}

The blocker here is animation-fill-mode: both;. I could not just move modal outside, so the solution was to override 'animation-fill-mode' to animation-fill-mode: none;. Animation still worked fine.

Arthro answered 30/12, 2015 at 8:37 Comment(1)
This is answer is seriously overlooked.Jesusa
D
2

If you use JQuery, you can use the appendTo() to append the modal to a specific element, in this case, the , in most case, a simple one line can move your modal on top of the backdrop regardless where your modal div's position

$("#myModal").appendTo("body");

here's the reference of the JQuery appendTo function: http://api.jquery.com/appendto/

I updated it to your fiddle http://jsfiddle.net/ZBQ8U/240/

Discreditable answered 27/9, 2017 at 2:59 Comment(1)
this is just amazing, I tried insertafter body but I had styling issues in the modal however, I used $('.modal').appendTo($('body')); and it workedOceanography
D
2

The problem persists if any ancestor of the [.modal] element has CSS property z-index set. The [.modal] element inherits the CSS z-index from that container element. While the [.modal-backdrop] is inserted into the [body] element dynamically from jQuery code, which has default z-index: 1040 from bootstrap.css.

I came out with two way CSS solution, is better than changing any other behavior of the default event and element.

  1. Set the z-index: 1041 or higher value for the parent element of the [.modal], that ancestor element is causing the [.modal] is underneath the [.modal-backdrop].

Or

  1. Set the z-index: 1039 or lower value for the [.modal-backdrop] in CSS file, if available. Because the HTML [.modal-backdrop] is not available in your code.

[Note: the CSS z-index property may require using !important flag]

[Note: default z-index: 1040 for [.modal-backdrop] is completely depended on bootstrap.css]

Dylandylana answered 17/11, 2021 at 11:32 Comment(0)
H
1

Another resolution for this problem is to add z-index: 0; to .modal-backdrop class in your bootstrap-dialog.css file if you don't want to modify bootstrap.css.

Hamnet answered 13/6, 2015 at 9:15 Comment(0)
B
1

Many times , you cannot move the modal outside as this affects your design structure.

The reason the backdrop comes above your modal is id the parent has any position set.

A very simple way to solve the problem other then moving your modal outside is move the backdrop inside structure were you have your modal. In your case, it could be

$(".modal-backdrop").appendTo("main");

Note that this solution is applicable if you have a definite strucure for your application and you cant just move the modal outside as it will go against the design structure

Bocock answered 14/6, 2016 at 6:33 Comment(0)
I
1

if we cannot delete backdrop and/or we have component framework such angular or vue we cannot move modal to the root. i did this trick: put my custom modal-backdrop container(with aditional class) as sibling for modal-dialog container and added some css

<div bsModal #moneyModal="bs-modal" class="modal fade" tabindex="-1" role="dialog">
    <!-- magic container-->
    <div class="modal-holder modal-backdrop" (click)="moneyModal.hide()"></div>
    <div class="modal-dialog modal-sm" role="document">
        <div class="modal-content">
            <div class="modal-body">
                ....
            </div>
        </div>
    </div>
</div>

and css

.modal-backdrop{z-index: -1}// or you can disable modal-backdrop
.modal-holder.modal-backdrop{z-index: 100}
.modal-holder + .modal-dialog {z-index: 1000}
Ineffable answered 27/4, 2017 at 13:58 Comment(0)
T
1

You could use this :

<div
  class="modal fade stick-up disable-scroll"
  id="filtersModal"
  tabindex="-1"
  role="dialog"
  aria-labelledby="filtersModal"
  aria-hidden="false"
  style="background-color: rgba(0, 0, 0, 0.5);" data-backdrop="false"
>
....
</div>

Adding style="" and data-backdrop false would fix it.
Typhoon answered 8/5, 2017 at 9:2 Comment(0)
M
1

For those using ASP.NET MVC,

Needing to move the modal div just before the </body> tag but can't do it because you are using a Layout page

Define a section in you _Layout.cshtml file just before the body tag, eg:

... some html in layout page ...
@RenderSection("bottomHTML", required: false)
</body>
</html>

Then in your view

@section bottomHTML 
{
<div class="modal fade" id="myModalID" role="dialog" tabindex="-1" aria-labelledby="demo-default-modal" aria-hidden="true">
... rest of the modal div HTML ...
}

This way, the modal HTML will be rendered before the body tag and the modal now should be displayed correctly..

Miceli answered 23/5, 2017 at 7:12 Comment(0)
A
1

Just remove the backdrop, insert this code in your css file

.modal-backdrop {
      /* bug fix - no overlay */    
      display: none;    
}
Arithmetician answered 19/9, 2019 at 0:9 Comment(0)
B
0

just remove z-index: 1040;

from this file bootstrap.css class .modal-backdrop

Blandishments answered 23/3, 2015 at 9:24 Comment(0)
L
0

I was missing the follow html

<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">

added it and worked without problems

Labaw answered 31/8, 2015 at 1:5 Comment(0)
C
0

Since I don't have the chance to move the modal markup since i added it in a partial template within a conditional what worked for me is add CSS bellow

.modal.fade {
    display: none;
}

Then, when boostrap add class "in" through js apply display: block and everything works fine.

Cording answered 30/12, 2015 at 20:37 Comment(0)
A
0

I Found that applying ionic framework (ionic.min.cs) after bootstrap coursing this issue for me.

Aldosterone answered 13/1, 2016 at 11:14 Comment(0)
F
0

If you can't put the modal to the root (if your use angular and the modal is in a controller for example), modifying bootstrap or using js is obviously a bad solution.

so saying you have your website structure:

//not working
<div>
    <div>
        <div>
            <modal></modal>
        </div>
    </div>
</div>

open your code inspector and move the modal to the root, it should be working (but no where you want):

//should be working
<div>
    <div>
        <div>

        </div>
    </div>
</div>
<modal></modal>

now put it in the first div and check if it's working: if yes check the next child until it's not working and find the div that is the problem;

//should be working
<div>
    <div>
        <div>

        </div>
    </div>
    <modal></modal>
</div>

Once you know which div is the problem you can play with the css display and position to make it work.

everyone has a different structure but in my case setting a parent to display: table; was the solution

Festination answered 22/1, 2016 at 16:39 Comment(0)
T
0

Put this code wherever you want

$('.modal').on('shown.bs.modal', function () {
    var max_index = null;
    $('.modal.fade.in').not($(this)).each(function (index , value){
        if(max_index< parseInt( $(this).css("z-index")))
            max_index = parseInt( $(this).css("z-index"));
    });
    if (max_index != null) $(this).css("z-index", max_index + 1);
});
Thora answered 17/3, 2016 at 12:56 Comment(0)
S
0

just move your modal outside of all div contents, place it mostly prior to closing of body.

Secretarial answered 6/9, 2016 at 11:12 Comment(0)
J
0

I had a similar problem that the fade was not working and the overlay stayed on the page. I had dynamic content added back to the page (refresh on some content only on modal action). I also had this $('#rejectModal-'+itemId).modal('hide') (itemId is dynamic id for multiple modals in a single page for rejecting some information) but the problem was still not gone.

The overlay was staying because my layout was not set to null in the partial view After setting this the problem was gone:

@{ 
    Layout = null;
}
Janson answered 30/5, 2017 at 7:25 Comment(0)
A
0

First make sure the modal is not in any parent div. Then add $('#myModal').appendTo("body")

It worked fine for me.

Anticlimax answered 1/8, 2017 at 11:13 Comment(0)
R
0

In Addition to all answers here, i found out, that the bootstrap4 "animated fadeIn" is also causing this error (not clickable modal behind background):

check if your modal is in the following parent tag (bootstrap animation)

<div class="animated fadeIn"></div>

I removed this tag - solved the problem for me.

Rakeoff answered 29/8, 2017 at 11:23 Comment(0)
P
0

this works for me.

<div class="modal fade" id="modalDecision" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" data-backdrop="false">
<div class="modal-dialog modal-sm">
    <div class="modal-content">
        <div class="modal-body text-center">
            <asp:Label runat="server" Height="30px">Please select recovery delivery option</asp:Label>
            <asp:LinkButton ID="btnEmail" CssClass="submit btn btn-primary" Width="100px" runat="server"
                OnClick="ModalRecovery">Email</asp:LinkButton>
            <asp:LinkButton ID="btnText" CssClass="submit btn btn-primary" Width="100px" runat="server"
                OnClick="ModalRecovery">Text</asp:LinkButton>
        </div>
    </div>
</div>

var element = $('#modalDecision');
    // also taken from bootstrap 3 docs
    $(element).on('shown.bs.modal', function (e) {
        // keep in mind this only works as long as Bootstrap only supports 1 modal at a time, which is the case in Bootstrap 3 so far...
        var backDrop = $("<div class='modal-backdrop' style='z-index:-1;opacity:.5'></div>");
        $(element).append($(backDrop));
    });
Primulaceous answered 11/11, 2017 at 1:56 Comment(0)
C
0

i encountred this problem, and after investigating my css, the main container (direct child of the body) had:

position: relative
z-index: 1

the backdrop worked well after i removed those two properties. You may also encounter this problem if the main wraper have a position: fixed

Carpometacarpus answered 6/12, 2017 at 8:35 Comment(0)
B
0

if you have nested modals this is the clue :

$('body').on('shown.bs.modal', '.modal', function (e) {
    e.stopPropagation();
    $(this).css("z-index", parseInt($('.modal-backdrop').css('z-index')) + 1);
});
Bengali answered 29/3, 2020 at 11:30 Comment(0)
H
0

For situations regarding frameworks that don't permit you to just move html/css around.

append the modal to the end of the body like

$("#EditModal").modal("show");
$("#EditModal").appendTo("body");

and destroy with

$("#EditModal").remove();

more at: https://weblog.west-wind.com/posts/2016/sep/14/bootstrap-modal-dialog-showing-under-modal-background

Hustings answered 11/5, 2021 at 19:35 Comment(0)
N
0

Well, in my case the bootstrap 5 modal-backdrop was getting the precedence over the modal itself because my modal div contained the CSS as z-index; auto. Which is where the modal-backdrop was taking precedence over the modal itself.

Nitz answered 1/7, 2023 at 18:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.