I have a DOM that looks like this:
<body>
<div id="main">
<iframe id="content"></iframe>
</div>
<div id="overlayWrapper">
<div id="overlay"><--THIS IS EMPTY DIV--></div>
</div>
</body>
Where inside the main div I have some other stuff too, which are not very relevant here. Now, these divs have the following CSS classes.
#main {
width: 100%;
position: static;
z-index: 2;
overflow: hidden;
}
#content {
width: 100%;
height: 500px;
z-index: 3000; // This doesn't seem to help.
}
#overlayWrapper {
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: 1000; // This needs to be at least 1000 for overlay to cover all elements in the page
position: fixed; // This seems to cause the problem?!
}
#overlay {
opacity: 1;
will-change: opacity;
transition: opacity 225ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
top: 0;
left: 0;
bottom: 0;
right: 0;
z-index: -1;
position: fixed;
background-color: rgba(0, 0, 0, 0.5);
-webkit-tap-highlight-color: transparent;
}
Now, this seems to work to some extend, as I see my overlay with the background-color value of rgba(0, 0, 0, 0.5) appearing on the screen.
The problematic part is that I cannot click on the stuff that are inside the iframe.
What I noticed is that this happens because of position: fixed style in the #overlayWrapper.
If I remove it, then I can click on the stuff from iframe but now the overlay is not visible any more.
Is it even possible to somehow keep the overlay but make the stuff on iframe clickable again?
I tried to add z-index: 3000; to iframe (i.e., to #content), but that doesn't seem to work.
Any ideas?
z-index only works on positioned elements. Which means the z-index that you applied to #content, which is the iframe, is not in effect.
#content {
position: relative;
z-index: 3000;
}
Here is the working jsfiddle.
PS: I added some links in #main to simulate the content you might have on your page.
It's because the z-index property of the div#main element should be placed before the the z-index of the div#overlayWrapper element.
Use position: relative on the <iframe> element because the z-index property gets in action with its relative.
#content {
width: 100%;
height: 500px;
/* This doesn't seem to help */
z-index: 3000;
position: relative;
}
Related
I am currently working on an "overlay pop up", which appears when I click a certain button.
It works quite well, however I struggle with the opacity
My main overlay div appears over the whole site and I gave it an opacity, so that you can see slightly the page in the background.
Over the overlay I put a content div, which shows the actual content (in that case a password changing request).
Anyway, I don't want the content box being transparent, but no matter what I try (z-index:10, opacity:1, position:relative etc.) it doesn't work.
It is still transparent, because I set up the opacity in the overlay div.
Here is the code:
CSS:
.changePasswordOverlay
{
height: 0%;
width: 100%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color:#fafafa;
opacity: 0.9;
overflow-y: hidden;
transition: 1s;
}
.passwordOverlayContent {
margin-left:40%;
margin-top:15%;
font-family:'source_sans_proregular';
font-size:15px;
position:relative;
}
HTML:
<div class="changePasswordOverlay">
<div class='passwordOverlayContent'>
.
.
.
</div>
</div>
you need to use rgba in background instead of opacity, because opacity has inheritance properties therefore children will get opacity as well
Note that rgba, stands for Red/Green/Blue/Alpha. and that's the alpha value that will work as your "opacity" value. The greater the alpha value the more opaque will be.
.changePasswordOverlay {
height: 100%; /* changed for demo */
width: 100%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .5);
overflow-y: hidden;
transition: 1s;
}
.passwordOverlayContent {
margin-left: 40%;
margin-top: 15%;
font-family: 'source_sans_proregular';
font-size: 15px;
position: relative;
color:white /* demo */
}
<div class="changePasswordOverlay">
<div class='passwordOverlayContent'>
text
</div>
</div>
Opacity applied the div and its children so .passwordOverlayContent will also have the same opacity, use background rgba instead of opacity
background-color: rgba(0, 0, 0, .9);
changed class :
.changePasswordOverlay
{
height: 0%;
width: 100%;
position: fixed;
z-index: 1;
top: 0;
left: 0;
background-color: rgba(0, 0, 0, .9);
overflow-y: hidden;
transition: 1s;
}
move the passwordOverlayContent container after changePasswordOverlay (instead of inside), and change your css to position:fixed to make it "opacity independant"
I've a full page fixed element to show 'This page is loading' gif image. But the page has contents which overflows the body. And user can scroll it over this fixed element. Is there a CSS way I can prevent this? I could have catch the event and stop it through JS. But a clean CSS way would be great.
.page-loading {
background: rgba($white, 0.7);
bottom: 0;
left: 0;
position: fixed;
right: 0;
top: 0;
transition: all 0.5s;
z-index: 14;
&__image {
height: 50px;
width: 50px;
}
}
I've refered this. But I want to control it from the component itself.(without JS)
As in the link you already provided, you have to apply overflow:hidden; to your body.
What is the trick to have a div 100% height always, even if the user is scrolling ?
I try this but it didn't work the height is only applied to the active window.
<body>
[...]
<div class="popup_container">...</div>
</body>
.popup_container {
position: absolute;
background-color: rgba(0, 0, 0, 0.65);
width: 100%;
min-height: 100%; /** even this didn't work **/
top: 0;
left: 0;
z-index: 12;
}
.popup_container {
position: fixed;
Change position to fixed. That should fix your problem ;)
Here's a jsfiddle
I have setup a fiddle to reproduce this issue. Only in android native browser, the scroll is working for the element beneath absolute positioned element. It doesn't seem to respect the z-index for scrolling.
html, body {
height: 100%;
overflow: hidden;
}
#scroll {
height: 100%;
overflow: scroll;
}
.overlay {
height: 100%;
width: 100%;
background-color: #333;
opacity: .4;
position: absolute;
z-index: 4;
left: 0;
top: 0;
}
Code: http://jsfiddle.net/s4vPV/5/
Result: http://fiddle.jshell.net/s4vPV/5/show/
Give your #scroll div a position:relative, and set the z-index:3 or something less, so that the browser respects what is on top of what.
I made some minor changes to your CSS, which solved the issue you are running into:
On your #scroll element, you are not defining the positioning, but you are defining the position on your .overlay element with absolute. This, plus apply the z-index property with a value of 4 to the .overlay element causes the overlay to stack on top of the #scroll element. Since the overlay has a height and width of 100%, you are causing the #scroll element to become inaccessible, due to the .overlay element covering it entirely.
#scroll {
height: 100%;
overflow: scroll;
}
.overlay {
height: 100%;
width: 100%;
background-color: #333;
opacity: .4;
position: absolute;
z-index: 4;
left: 0;
top: 0;
}
Basically, if the browser were sheets of paper that were perfectly stacked upon one another, you wouldn't be able to read "access" at the bottom of the stack.
If you are trying to style your scroll bars, I would recommend looking into styling them directly. If not, all you have to do is place a position: relative on the #scroll and a z-index: 5; which will solve this issue.
Here is a jsfiddle with the solution: http://jsfiddle.net/dmidify/s4vPV/10/
I convert any div on my webpages to pop-up box by adding a class, turnIntoOverlay , to the div. (See JSFiddle)
.turnIntoOverlay {
position: fixed;
background-color: white;
top: 60px;
max-width: 680px;
z-index: 80;
border: 6px solid #BBB;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
max-height: 800px;
overflow: auto;
padding:10px;
}
Now when the pop up is displayed I also want to create a mask that puts up a faded layer(or mask) to the rest other page elements that appear below popup box. To create this mask, I resorted to pure css approach using psuedo selectors, so that the mask is shown/hidden simply when a popup box( a turnIntoOverlay element) is visible. I added the following css:
.turnIntoOverlay:after {
content: "";
background-color: whitesmoke;
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.5;
top: 0;
left: 0;
}
Everything works fine except that the mask appears on the pop up as well even when I keep the z-index lower than of popup. Also to my surprise, it works only when z-index=-1.
Can you please suggest how to rectify this ?
See JSFiddle here
The problem is the stacking context. The :after content can not be below it's parent, except if the parent would be out of the stacking context which in your case is no option. z-index: -1 works because it's a special case and has priority over the parents content. That's why it does not effect the text, but effects background and border. See the list on Stacking Contexts. Your :after { z-index: -1 } is nr. 2 in the list.
Your only option would be using an additional wrapper:
<div class="turnIntoOverlay"><div>this div is convertible to pop up!<input/></div></div>
moving your current styles for .turnIntoOverlay to .turnIntoOverlay > div and applying the overlay to the outer div with a positive z-index:
.turnIntoOverlay:after {
z-index: 1;
}
Here is a demo.
Unfortunately IE8 and below are buggy on that. Also they do not know opacity and using -ms-filter does not work on elements without layout like pseudo classes :before and :after are.
Of course, if you'd use an additional wrapper anyway, you could just give the other wrapper the background-color. No need for :after then:
.turnIntoOverlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: skyblue; /* for old browsers */
background-color: rgba(135, 206, 235, 0.4);
}
Compared to the pseudo class approach, this includes a little fix for IE8 and below. Can be made even better by using a transparent png which is applied to IE. With that, it looks quite the same in every browser (after IE6 I would say).
Here is a demo.
My solution is to use both :before and :after to solve your problem:
.turnIntoOverlay {
position: fixed;
background-color: white;
top: 60px;
max-width: 680px;
border: 6px solid #BBB;
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.5);
max-height: 800px;
overflow: auto;
padding:10px;
z-index: 80;
}
.turnIntoOverlay:before {
content: "";
background-color: skyblue;
position: fixed;
width: 100%;
height: 100%;
z-index: -1;
opacity: 0.4;
top: 0;
left: 0;
}
.turnIntoOverlay:after{
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
background-color: white;
z-index: -1;
content: "";
}
JSFiddle
I took out the position: fixed from .turnIntoOverlay and now it works.