Reputation: 8988
I have a simple set up where I have a hamburger style menu that enables an off canvas menu (something like this) that slides the main content to the right.
<div class="layout-wrapper" >
<div class="layout-menu"></div>
<header class="layout-header"></header>
<div class="layout-content"></div>
</div>
So I have a container div: layout-wrapper
.
I have the menu: layout-menu
, with absolute positioning so that I can put the main content on top of it.
I have the header: layout-header
, with fixed positioning so that it always will remain on top when I scroll the content
I have the content: layout-content
.
My problem is that the layout-content
is not visible unless i add position: relative
to it. Why do I have to do that? Have I done a stupid mistake?
Here is a plunker showing the problem. Enable the commented line in the CSS to see what it should look like.
Upvotes: 0
Views: 2195
Reputation: 288680
The problem is that .layout-menu
is a positioned element:
.layout-menu {
position: absolute;
}
But .layout-content
is not:
.layout-content {
position: static; /* default value */
}
According to CSS 2.1 spec,
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. [...]
Each stacking context consists of the following stacking levels (from back to front):
- the background and borders of the element forming the stacking context.
- the stacking contexts of descendants with negative stack levels.
- a stacking level containing in-flow non-inline-level descendants.
- a stacking level for floats and their contents.
- a stacking level for in-flow inline-level descendants.
- a stacking level for positioned descendants with 'z-index: auto', and any descendant stacking contexts with 'z-index: 0'.
- the stacking contexts of descendants with positive stack levels.
That means that .layout-menu
, which falls in the stacking level 6, will be displayed in front of .layout-content
, which falls in the stacking level 3.
However, if you use
.layout-content {
position: relative;
}
Now .layout-content
will fall in the stacking level 6 too.
Then,
Boxes with the same stack level in a stacking context are stacked back-to-front according to document tree order.
Therefore, since .layout-content
comes after .layout-menu
in the document tree, .layout-content
will be displayed in front of .layout-menu
.
Upvotes: 1
Reputation: 91
It's not a mistake, you have to set position: relative
for the layout-content
so it can overlap layout-menu
.
In your Off Canvas Menu example the content has also a position: relative
.
Upvotes: 1
Reputation: 7218
This is because an element needs to have a position
property other than static
(which is the default) for the z-index
property to work. This means it will not only work with position: relative
. it will also work with position: absolute
and position: fixed
.
Give this a read to understand z-index better
Upvotes: 1