How to make child element higher z-index than parent?
This is impossible as a child's z-index
is set to the same stacking index as its parent.
You have already solved the problem by removing the z-index from the parent, keep it like this or make the element a sibling instead of a child.
Z-Index issue with child elements
remove .parent
's z-index: 1
.parent{
position: relative; height: 200px; width: 200px; display: inline-block;
}
.parent:hover .child{
display: block;
}
.child{
position: absolute; height: 50px; width: 50px; z-index: 2; display: none;
}
<div class="parent" style="background-color: hotpink;">Parent 1<div class="child" style="background-color: yellow; margin-left: 180px; margin-top: 50px;">Child 1.1</div></div>
<div class="parent" style="background-color: green;">Parent 2<div class="child" style="background-color: greenyellow; margin-left: -30px;">Child 2.1</div></div>
How does parent's z-index affect the child's z-index?
By default, all background colour goes behind the text. the z-index
default is auto which states "Sets the stack order equal to its parents". However, using z-index
on the child will move it out of the natural stack order and place it behind the background. If you change the parent to also have a Z-Index then it will rejoin the stack and the background colour will again appear behind the text.
Both parent and child are set to AUTO. Both in the same stack.
#parent {
position: absolute;
background: red;
width: 100px;
height: 100px;
}
#child {
position: absolute;
top: 50px;
left: 50px;
transform: translateX(20px);
}
<div id="parent">
<div>
qqq
</div>
<div id="child" >
test
</div>
</div>
z-index between Children and Parents
If #map-container
is positioned (i.e. not static), this is not possible, because of the way z-index is compared:
body
(or any other positioned parent element) is the reference for both #map-container
and #nav-bar
. Any z-index
you give them is calculated in respect to the parent element. So the one of the 2 elements with the higher z-index will be rendered above the other one and all its child elements. Z-index of #tooltip
will only be compared with other children of #map-container
.
You could do as Nacho said and statically position #map-container
. You can simulate fixed positioning via Javascript, if you like.
If you cannot do that, you need to change your markup, so that #nav-bar
and #tooltip
have a common positioned parent element. Either move #nav-bar
inside #map-container
, or #tooltip
out of it.
Why can't an element with a z-index value cover its child?
There are two important things you need to know: the painting order and the stacking context. If you refer to the specification, you can find how and when elements are painted.
- Stacking contexts formed by positioned descendants with negative z-indices (excluding 0) in z-index order (most negative first) then tree order.
All positioned, opacity or transform descendants, in tree order that fall into the following categories:
- All positioned descendants with 'z-index: auto' or 'z-index: 0', in tree order.
- Stacking contexts formed by positioned descendants with z-indices greater than or equal to 1 in z-index order (smallest first) then tree order.
It's clear from this that we first paint elements with negative z-index
at step (3), then the one with z-index
equal to 0 at step (8), and finally the ones with positive z-index
at step (9), which is logical. We can also read in another part of the specification:
Each box belongs to one stacking context. Each box in a given stacking context has an integer stack level, which is its position on the z-axis relative to other boxes in the same stacking context. Boxes with greater stack levels are always formatted in front of boxes with lower stack levels. Boxes may have negative stack levels. Boxes with the same stack level in a stacking context are stacked bottom-to-top according to document tree order.
To understand when each element will be painted you need to know its stacking context and its stack level inside this stacking context (defined by z-index
). You also need to know whether that element establishes a stacking context. This is the tricky part, because setting z-index
will do this:
For a positioned box, the z-index property specifies:
- The stack level of the box in the current stacking context.
- Whether the box establishes a stacking context
Values have the following meanings:
<integer>
This integer is the stack level of the generated box in the current stacking context. The box also establishes a new stacking context.
auto
The stack level of the generated box in the current stacking context is 0. The box does not establish a new stacking context unless it is the root element.
Now we have all the information to better understand each case. If the parent element has a z-index
value of something other than auto
, then it will create a stacking context, thus the child element will be painted inside whatever their z-index
is (negative or positive). The z-index
of the child element will simply tell us the order of painting inside the parent element (this covers your second point).
Now, if only the child element has a positive z-index
and we set nothing on the parent element, then considering the painting order, the child will be painted later (in step (9)) and the parent in step (8). The only logical way to paint the parent above is to increase the z-index
, but doing this will make us fall into the previous case where the parent will establish a stacking context and the child element will belong to it.
There is no way to have the parent above a child element when setting a positive z-index
to the child. Also there is no way to have the parent above the child if we set a z-index
to the parent element different from auto
(either positive or negative).1
The only case where we can have a child below its parent is to set a negative z-index
on the child element and keep the parent at z-index: auto
, thus this one will not create a stacking context and following the painting order the child will be painted first.
In addition to z-index
, there are other properties that create a stacking context. In case you face an expected stacking order, you need to consider those properties, too, in order to see if there is a stacking context created.
Some important facts that we can conclude from the above:
- Stacking contexts can be contained in other stacking contexts, and together create a hierarchy of stacking contexts.
- Each stacking context is completely independent of its siblings: only descendant elements are considered when stacking is processed.
- Each stacking context is self-contained: after the element's contents are stacked, the whole element is considered in the stacking order of the parent stacking context. ref
1: there is some hacky ways if we consider the use of 3D transformation.
Example with an element going under its parent element even if this one has a z-index
specified.
.box {
position:relative;
z-index:0;
height:80px;
background:blue;
transform-style: preserve-3d; /* This is important */
}
.box > div {
margin:0 50px;
height:100px;
background:red;
z-index:-1; /* this will do nothing */
transform:translateZ(-1px); /* this will do the magic */
}
<div class="box">
<div></div>
</div>
stacking with z-index, child element on top over parent sibling
I removed the position absolute from the yellow div and removed the z-index from the green div. Maybe this is something as you said.
.parent {
background-color: yellow;
top: 0;
left: 0;
height: 200px;
width: 200px;
z-index: 1;
}
.child {
background-color: red;
position: relative;
top: 10px;
left: 20px;
height: 50px;
width: 150px;
z-index: 2;
}
.other-guy {
background-color: green;
position: absolute;
top: 40px;
left: 100px;
height: 200px;
width: 200px;
}
<div class="parent">Chillin in the background
<div class="child">I really want to be on top.</div>
</div>
<div class="other-guy">I want to be in the middle!</div>
Z-index issue : Stack a child element behind a parent container
Set the parent element z-index
to initial
html {
padding: 20px;
font: 12px/20px Arial, sans-serif;
}
div {
opacity: 0.7;
position: relative;
}
.parent {
z-index: initial;
opacity: 1;
position: absolute;
top: 40px;
left: 100px;
width: 330px;
border: 1px dashed #900;
background-color: #fdd;
padding: 40px 20px 20px;
height: 200px;
}
.child {
z-index: -1;
position: absolute;
top: 10px;
left: 260px;
width: 150px;
height: 110px;
border: 1px dashed #009;
padding-top: 125px;
background-color: #ddf;
text-align: center;
}
https://jsfiddle.net/3269rjqh/1/
Related Topics
Margin-Top Percentage Does Not Change When Window Height Decreases
Make Input Value Uppercase in CSS Without Affecting the Placeholder
Which Is Better to Use in CSS, Percentage or Pixels
What Is That Thing Between CSS "Selectors" Called
Infinite Image Slider with Pure CSS3
Datagrid/Celltable Styling Frustration -- Overriding Row Styles
How to Do Browser Specific Conditional CSS Inside a *.CSS File
Unicode Character for "X" Cancel/Close
Why Doesn't This CSS Transition Work on Svg Inside an Anchor
How to Nest Media Queries Within Media Queries
:Last-Child Pseudo Class Selector in CSS and Internet Explorer
Input[Type=Number] Placeholder Color in Ff29+
Which Browsers Support Webkit CSS
Differencebetween Applying CSS Transition Property in Hover Rather Than in Its Normal State
Background-Position Not Working with CSS Animation and Linear Gradient