Fixed element is relative to component, not window in Angular2 - css

I have an angular2 application using the Angular2-material library for styling. I'm trying to add a FAB (Floating Action Button) to hover in the right corner of the application, but it's fixing itself to its parent component, and not the window.
The hierarchy of the application is as follows:
app.component
|-detail.component
Within the app.component template, I am using the md-sidenav-layout directive with router-outlet in the body of the layout directive:
<md-sidenav-layout>
<md-sidenav #sideNav (open)="closeStartButton.focus()">
<router-outlet name="navMenu"></router-outlet>
<br>
<button md-button #closeStartButton (click)="sideNav.close()">Close</button>
</md-sidenav>
<md-toolbar color="primary">
<button md-icon-button (click)="sideNav.toggle()">
<md-icon class="md-24">menu</md-icon>
</button>
<span>{{title}}</span>
</md-toolbar>
<div role="main">
<router-outlet></router-outlet>
</div>
</md-sidenav-layout>
Inside the detail component template, I have the following at the top of the template:
<button md-mini-fab class="fab" (click)="toggleAdd()">
<i class="material-icons">add</i>
</button>
And the css for that component:
.fab {
display: block;
position: fixed;
right: 2rem;
bottom: 2rem;
z-index: 10;
}
However, when I navigate to the detail page, the .fab is positioned relative to the component, not the window. I've tried using encapsulation: ViewEncapsulation.None on the detail component, but that doesn't affect it either. Is there a way to keep the fab defined within the detail component, but have it still be fixed relative to the window?

Look for something applying a CSS transform up the chain. In my case I was applying a transform via Angular animations. Apparently transform breaks position:fixed. Why does `transform` break `position: fixed`?
I hope I can figure out how to make this work, now.

in your app.component.html add this code:
<md-sidenav-container>
<md-sidenav mode="side" opened="true">Drawer content</md-sidenav>
<div class="my-content">Main content</div>
</md-sidenav-container>
global styles.css:
html, body, material-app, md-sidenav-container, .my-content {
margin: 0;
width: 100%;
height: 100%;
}
it works for me! ;)

I answered a very similar question here.
The gist: I solved this with a quite heavy workaround. I removed the FAB from the main content, defined a secondary router outlet in my template (outside md-sidenav-layout), created a standalone component for the FAB, and used an Observable in a service to broadcast the click events to the main components.
The answer in the other thread contains code samples and a working plunker example.

Related

Toggle icon not appearing on React-Accessible-Accordion

I am implementing React-accessible-accordion in my React application.The click functionality is working fine however, I do not see the arrow icon appearing on the accordion. I tried to compare it with the DOM structure shown in the example in npm and I see the div for the icon itself is not getting added to my DOM.
My code-
import React from 'react';
import ReactDOM from 'react-dom';
import {
Accordion,
AccordionItem,
AccordionItemTitle,
AccordionItemBody,
} from 'react-accessible-accordion';
import 'react-accessible-accordion/dist/fancy-example.css';
import 'react-accessible-accordion/dist/minimal-example.css';
<div className="container">
<Accordion>
<AccordionItem>
<AccordionItemTitle>
<h4>Hello, This is me..</h4>
</AccordionItemTitle>
<AccordionItemBody>
Some Text
</AccordionItemBody>
</AccordionItem>
</Accordion>
</div>
The arrow icon comes from the
<div class="accordion__arrow" role="presentation"></div>
and this is not getting added for me. Any reason why is that happening. I am using the exact demo code shown in on npm site.
Link I have referred-
https://www.npmjs.com/package/react-accessible-accordion
In my knowledge, the only thing I have not added is,
document.querySelector('[data-mount]')
Is that the reason my arrow icons are not loading?
I am not sure if this is an open bug but the examples shown has these icons in each of the accordion.
Did you import the CSS style ?
// Demo styles, see 'Styles' section below for some notes on use.
import 'react-accessible-accordion/dist/fancy-example.css';
Adding below in AccordionTitle, solves the issue-
<h3 className="u-position-relative">
Accessible Accordion
<div className="accordion__arrow" role="presentation"/>
</h3>
You need to do couple to things to make it work:
1] You need to copy all the contents of this file'react-accessible-accordion/dist/fancy-example.css'; to another file because we going to override some classes.
2] You need to add a div in the AccordionItemTitle
<AccordionItemTitle>
<h4>Hello, This is me..</h4>
<div className="accordion__arrow" role="presentation" />
</AccordionItemTitle>
3] in the stylesheet you createdm type the following styles
.accordion__item {
position: relative;
}
.accordion__arrow {
display: inline-block;
width: 24px;
height: 12px;
position: absolute;
top: 40px;
right: 15px;
margin-top: -6px;
}
The toggle button should appear after that.
add yhis piece of code
<AccordionItemTitle>
<h3 className="u-position-relative">
Accessible Accordion
<div className="accordion__arrow" role="presentation" />
</h3>
</AccordionItemTitle>

How to overlap component?

I have the following angular component lets call it child-component
<div>
<a-component-tag></a-component-tag>
<router-outlet></router-outlet>
</div>
which is itself being rendered into another router-outlet like this
<div>
<top-component></top-component>
<router-outlet></router-outlet>
<div>
I would like the component that is rendered in the first router-outlet above to either render below a-component-tag or cover a-component-tag, depending on the user clicking a maximize, minimize button. It shouldn't cover anything but a-component-tag (i.e. it should not cover top-component).
This component is defined by
<div id="thiscomp" [ngclass]="max?cover:minimize">...</div>
I tried to define these two classes as
.cover{
position: absolute;
top: 0;
left: 0;
z-index:100;
}
.minimize {
margin-top:30px;
}
but the cover class is not working: Some of the subcomponents in the thiscomp div are rendered above some stay minimized.
You're trying to change the order in which two DOM elements appear -- there are better techniques than absolute positioning available for that.
The javascript in this example is just for demo; the work is being done in the CSS:
document.getElementById("example").onclick = function() {
document.getElementById("container").classList.toggle('flip');
}
#container {display: flex; flex-direction:column}
#container.flip {flex-direction: column-reverse}
<div id="container">
<div class="componentA">Component A</div>
<div class="componentB">Component B</div>
</div>
<button id="example">Toggle</button>

Angular Material Side Bar with "Half" side mode

I am working on the dynamic side bar for our project, basically what we want to do is to set up a dynamic side bar when user click on the side bar it will spread when user click back sidebar should collapse and show only icons (but not totally collapse it will keep the icons) for example before user click the icon. We are using sidenav.toggle()from angular material function which basically closes the sidebar completely and if I don't use toggle() function "Side" mode for navbar does not work. So I want collapse to icon with side mode. (The other reason we need to keep the side mode is that we also need to make sure when user spread the sidebar, right side content should push to right)
After user click the icon
Is there a way to do that?
Thanks.
Option 1: Generating Automatically:
You can create a navigation component from templates provided by Material itself using 'Angular CLI component schematics'
ng generate #angular/material:nav your-component-name
The above command will generate a new component that includes a toolbar with the app name and a responsive side nav based on Material breakpoints.
See more about angular material schematics here
Option 2: Implementing Manually:
To implement that, you just have to refer these two links:
Resizing Sidenav | Angular Material
Navigation List | Angular Material
glance through the following code. Implementation will be something like this:
<mat-drawer-container class="example-container mat-typography" autosize>
<mat-drawer #drawer mode="side" disableClose="true" opened="true">
<button mat-mini-fab (click)="isExpanded = !isExpanded" color="warn" style="margin: 10px;">
<mat-icon aria-label="Menu">menu</mat-icon>
</button>
<mat-nav-list>
<mat-list-item>
<mat-icon mat-list-icon>person</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management A</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>assignment</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management B</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>domain</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management C</h4>
</mat-list-item>
<mat-list-item>
<mat-icon mat-list-icon>folder_shared</mat-icon>
<h4 mat-line *ngIf="isExpanded">Management X</h4>
</mat-list-item>
</mat-nav-list>
</mat-drawer>
<div class="example-sidenav-content">
You cards and screen Contents goes here..
Will be pushed towards right on expanding side navbar.
</div>
</mat-drawer-container>
I did this with a bit of CSS
mat-sidenav:not(.mat-drawer-opened) {
transform: translate3d(0, 0, 0) !important;
visibility: visible !important;
width: 60px !important;
overflow: hidden;
}
So when the draw is NOT open, the width of the sidenav is 60px and not 0. Just enough to show your icons.
OK, the next issue is that you'll need to hide a bunch of stuff like button name and other descriptive stuff, for me I need to change the height of the profile image and hide additional text. I did this in the same way as above using the :not selector:
mat-sidenav:not(.mat-drawer-opened) div.leftNav div.navProfile img {
width: 40px; margin: 16px 0 0px 0;
}
mat-sidenav:not(.mat-drawer-opened) .navTitle,
mat-sidenav:not(.mat-drawer-opened) .profileTitle {
display: none;
}
When collapsed I didn't want to show the button names so I wrapped the name in a *ngIf
<span class="navName" *ngIf="opened">{{ page?.name }} </span>
This should work, and it does but there is a problem. The ngIf is bound to the opened event and you will notice a delay when the event is firing (to account for it animation) to show your labels when the drawer is open.
To fix this I had to delve into the api of sidenav and found an eventemitter call openedStart and closedStart. I created a new bool in the component class,
showNavLabels: boolean;
then bound the events to this bool in the HTML.
<mat-sidenav class="sidenav" #sidenav mode="side" [(opened)]="opened"
(openedStart)='showNavLabels = !showNavLabels'
(closedStart)='showNavLabels = !showNavLabels' >
I am sure there is better way as I am not that experienced with Angular yet.
I hope it helps you out.
I created an example based on scss. Maybe someone can help to create the mobile version according to this sample.
Step 1: Add below style to styles.scss
// src/styles.scss
:root {
--menu-width-open: 200px;
--menu-width-closed: 64px;
}
.mat-drawer-container {
.mat-drawer {
box-sizing: content-box;
width: var(--menu-width-open);
transition: all 0.3s ease-in-out !important;
}
.mat-drawer-content {
// transform: translateX(200px);
margin-left: var(--menu-width-open) !important;
transition: all 0.3s ease-in-out !important;
}
&.container-closed {
.mat-drawer {
width: var(--menu-width-closed);
}
.mat-drawer-content {
// transform: translateX(64px) !important;
margin-left: var(--menu-width-closed) !important;
}
}
}
Step 2: Add drawer to app.componenet.html
<mat-drawer-container class="example-container" autosize [ngClass]="{ 'container-closed': !showFiller }">
<mat-drawer #drawer class="example-sidenav" mode="side" disableClose="true" opened="true">
<button (click)="showFiller = !showFiller" mat-raised-button>click</button>
</mat-drawer>
<div class="example-sidenav-content">
<router-outlet></router-outlet>
<button type="button" mat-button (click)="drawer.toggle()">Toggle sidenav</button>
</div>
</mat-drawer-container>
Step 3: And add showFiller = false; to app.component.ts file.
// app.component.ts
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
})
export class AppComponent {
showFiller = false;
}
There is a feature request for this https://github.com/angular/material2/issues/1728
if you read the comments you'll also find a few examples on how to implement it yourself while it's not officialy available.

Any way to anchor a footer section in React?

I created a wrapper for my app in React. I am trying to get the footer to stay at the absolute bottom of the page but when the children render, the footer stays at the original bottom of the page and does not resize with the page. Code below. (imagine a scrollable page with a footer in the middle now after child renders).
import React, { Component } from 'react';
import Header from "./Header";
import Footer from "./Footer";
export default class Wrapper extends Component {
render() {
return (
<div className="app-wrapper">
<Header/>
<div className="content">
{this.props.children}
</div>
<div>
<Footer/>
</div>
</div>
);
}
}
I'm not that good at CSS. Any ideas as to what I could try? I have already tried googling around for solutions to no avail.I have tried the basic solutions such as position:relative; left:0; bottom:0; right:0; position: fixed, position: absolute etc.
You should give position: relative|fixed (depending on your needs) to the parent container.
For exemple :
<div style={{ position: 'fixed', bottom: '0' }}>
<Footer />
</div>
HTML dock to bottom
sorry for the confusion guys. I had the style redefined in my css file so my styles were being overridden. :(

Bootstrap Modal sitting behind backdrop

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?
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.
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);
});
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><span class="fa fa-lg fa-home"></span> Home</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
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'));
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!
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>
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);
}
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.
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.
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.
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}
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.
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..
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/
Just remove the backdrop, insert this code in your css file
.modal-backdrop {
/* bug fix - no overlay */
display: none;
}
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.
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
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]
just remove z-index: 1040;
from this file bootstrap.css class .modal-backdrop
I was missing the follow html
<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
added it and worked without problems
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.
I Found that applying ionic framework (ionic.min.cs) after bootstrap coursing this issue for me.
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
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);
});
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
just move your modal outside of all div contents, place it mostly prior to closing of body.
First make sure the modal is not in any parent div.
Then add
$('#myModal').appendTo("body")
It worked fine for me.
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.
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));
});
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
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;
}
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);
});

Resources