z-index
is not ignored for flex-items (immediate children of flex-container, element with display: flex
or display: inline-flex
) or grid-items (immediate children of grid-container, element with display: grid
or display: inline-grid
).
Specs quotation
From W3C Flexbox specs:
Flex items paint exactly the same as inline blocks CSS21, except that order
-modified document order is used in place of raw document order, and z-index
values other than auto
create a stacking context even if position
is static
.
From W3C CSS Grid Layout specs:
Grid items can overlap when they are positioned into intersecting grid areas, or even when positioned in non-intersecting areas because of negative margins or positioning. The painting order of grid items is exactly the same as inline blocks CSS21, except that order-modified document order is used in place of raw document order, and z-index
values other than auto
create a stacking context even if position
is static
(behaving exactly as if position
were relative
). Thus the z-index
property can easily be used to control the z-axis order of grid items.
Flexbox example
So assume we have this layout with overlapping (.flex-item-two
overlaps .flex-item-one
using e.g. negative margins):
.flex {
display: flex;
align-items: center;
}
.flex-item-one {
width: 100px;
height: 100px;
background-color: red;
margin-right: -50px;
}
.flex-item-two {
width: 200px;
height: 200px;
background-color: green;
}
<div class="flex">
<div class="flex-item flex-item-one">One</div>
<div class="flex-item flex-item-two">Two</div>
</div>
If flex-item-one
index is bigger than .flex-item-two
's, .flex-item-one
then overlaps .flex-item-two
.
.flex {
display: flex;
align-items: center;
}
.flex-item-one {
width: 100px;
height: 100px;
background-color: red;
margin-right: -50px;
z-index: 1;
}
.flex-item-two {
width: 200px;
height: 200px;
background-color: green;
}
<div class="flex">
<div class="flex-item flex-item-one">One</div>
<div class="flex-item flex-item-two">Two</div>
</div>
CSS Grid example
#grid {
display: inline-grid;
width: 250px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr
}
#A {
grid-column: 1 / span 2;
grid-row: 2;
align-self: end;
background-color: #4f81bd;
}
#B {
grid-column: 1;
grid-row: 1;
z-index: 10;
background-color: #8064a2;
}
#C {
grid-column: 2;
grid-row: 1;
align-self: start;
margin-left: -20px;
background-color: #f79646;
}
#D {
grid-column: 2;
grid-row: 2;
justify-self: end;
align-self: start;
background-color: #9bbb59;
}
#E {
grid-column: 1 / span 2;
grid-row: 1 / span 2;
z-index: 5;
justify-self: center;
align-self: center;
background-color: #c0504d;
}
#grid > * {
color: #fff;
display: flex;
align-items: center;
justify-content: center;
padding: 20px 40px;
font-size: 32px;
}
#C, #D {
padding: 10px 20px;
}
<div id="grid">
<div id="A">A</div>
<div id="B">B</div>
<div id="C">C</div>
<div id="D">D</div>
<div id="E">E</div>
</div>
It does not apply to elements with static position.
I'm asking why that is. – Nurmi