I have the following setup:
<div style="z-index: 10">
<div>Whatever</div>
</div>
<div style="z-index: 9">
<div><div>Haaaleluia</div></div>
</div>
Of course... I oversimplified the setup but that's the main idea. The "whatever" div is overlapped by the "Haaaaleluia" div. Of course because the first parent has bigger z-index "whatever" is visible and "haaaleluia" is not.
Without changing the setup (and to be clear that includes keeping the parents z-indexes), how can I make "Haaaaleluia" to be on top?
For those asked for print here it is... also thank you for help:
The big bad map is the second div.
The tutorial is the first div.
The panel with orders is child of the map. I need it to be on top. If I set whole map on top, the tutorial is not visible any more. If I keep the map behind the orders panel is not visible any more.
In short: you can't. It's not possible to have a child of a parent element with a z-index
lower than a sibling, and give that child a higher z-index value than the parent's sibling, as the inherited z-index is relative to the parent (see this question for someone coming up against the same thing).
However, depending on your setup, you can remove the z-indices completely, and let the browser place your top div
above the one below. You could then play around with giving just the children a z-index
value.
Josh Comeau has a great article going into depth on the problem and various solutions/workarounds.
Without changing the locations, z-index
, or rearranging any of the elements, the only way I can think of that would allow the div
underneath to appear would be to either change the visibility
, display
or opacity
of the div
overlapping the one you want to see.
That is, use one of the following CSS styles on the parent div
of "Whatever":
visibility: hidden;
display: none;
opacity: 0;
You're basically asking to display an element above another element that has a higher z-index
, which defeats the purpose of having a z-index
. If you're trying to control how elements overlap, it really should be done with z-index
. I would suggest you rethink how your elements are organized (maybe move the "Haaaleluia" div
outside of its parent and assign it its own z-index
). Otherwise, I might suggest you consider creating a duplicate of "Haaaleluia" to display above "Whatever", which may or may not suit your situation.
Edit: Looking at the image you've provided, changing the parent of the order box to the parent of the tutorial div may work for you. Here is a demo using jQuery that may help illustrate the point - just change the hover event to whatever it is that starts the tutorial. Another option may be to clone the order box to lay on top of the one below, but with a higher z-index
(so that the user only sees one, but the clone overlaps everything else). This is assuming that your map div is positioned either absolutely or relatively. Hope that helps.
Nice design.
Ok so I'll first say that I believe the solution to your layering problem, as others have already suggested, is moving that box outside of its parent (the map).
But you set some constraints, so I'll try to break as few as possible. I don't know how to do this without breaking any of your constraints. Z-index is inherited (again, others have pointed this out), so you can't break out of your parents' layer with only that tool.
So here's one way you could get the same effect, using javascript. It's ugly, and might cause you more headaches later, but it should at least work:
If you're using jQuery, you can get elements' position relative to the document with the .offset()
function. After that it's fairly simple:
$(document).ready( function() {
$("a[href='#overlay']").click( function() {
// 1: get the position
pos = $('.wrap').offset();
// 2: make a copy
halecopy = $('.bottom .wrap').clone();
// 3: hide the original
$('.bottom .wrap').css({opacity: 0});
// 4: Insert new label on top of everything
$('body').prepend(halecopy);
// position the new label correctly
halecopy.css({position:'absolute',
top: pos.top,
left: pos.left,
'z-index': 2});
// show the "top" layer
$('.top').fadeIn();
});
$("a[href='#hide']").click( function() {
$('.top').fadeOut( function() {
// remove the label copy
halecopy.remove();
// show the original again
$('.bottom .wrap').css({opacity: 1});
});
});
});
That script works for me on this markup:
<div class="top">
<div class="label">
<p>Whatever</p>
</div>
</div>
<div class="bottom">
<div class="wrap">
<div class="label">
<p>Haaaleluuuuia!</p>
</div>
</div>
</div>
<a href="#overlay">show</a>
<a href="#hide">hide</a>
With these styles:
.top,
.bottom {
position: absolute;
top: 10%;
left: 3%;
}
.top {
z-index: 1;
padding: 2%;
background: rgba(0, 127, 127, 0.8);
display:none;
}
.bottom {
z-index: -1;
padding: 3%;
background: rgba(127, 127, 0, 0.8);
}
.label {
color: #fff;
}
.wrap {
outline: 1px dashed rgba(127, 0, 0, 0.8);
background: rgba(127, 127, 127, 0.8);
}
.bottom .label {
z-index: 10;
}
And here's a handly jsfiddle demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With