Flexbox, z-index & position: static: Why isn't it working?
Like you wrote in your question, elements do not need to be positioned for z-index
to work in a flex container.
Flex items can participate in a z-index
stacking order even with position: static
, which is not true for other CSS box models (except Grid) where z-index
only works on positioned elements.
4.3. Flex Item Z-Ordering
Flex items paint exactly the same as inline blocks, except
thatorder
-modified document order is used in place of raw document
order, andz-index
values other thanauto
create a stacking context
even ifposition
isstatic
.
The reason z-index
isn't working in your code is that div.header
and div.core
are not flex items. They are children of body
, but body
is not a flex container.
In order for z-index
to work here, you'll need to apply display: flex
to body
.
Add this to your code:
body {
display: flex;
flex-direction: column;
}
Revised Demo
More details: https://stackoverflow.com/a/35772825/3597276
Why is z-index ignored with position:static?
Because position: static
means "Ignore all the positioning instructions from left
, top
, z-index
, etc.".
'z-index'
Value: auto | <integer> | inherit
Initial: auto
Applies to: positioned elements
— http://www.w3.org/TR/CSS21/visuren.html#z-index
An element is said to be positioned if its 'position' property has a value other than 'static'.
— http://www.w3.org/TR/CSS21/visuren.html#positioned-element
Why does z-index not work?
The z-index
property only works on elements with a position
value other than static
(e.g. position: absolute;
, position: relative;
, or position: fixed
).
There is also position: sticky;
that is supported in Firefox, is prefixed in Safari, worked for a time in older versions of Chrome under a custom flag, and is under consideration by Microsoft to add to their Edge browser.
z-index not working on text inside flex item
In a flex container, z-index
works without the need for positioning properties (source).
In other words, flex items can use z-index
with position: static
.
However, your text is not a flex item. It is a child of a flex item, so this z-index
method won't work.
As a solution, make the flex items into (nested) flex containers.
.row { display: flex; margin: auto; padding: 1rem; background-color: red; width: 70%; max-width: 1043px; box-sizing: border-box;}#row-1 { background: red;}#row-1 div { position: relative; box-sizing: border-box; margin: .5rem; padding: 2.488rem 1rem; flex: 1; z-index: 1; display: flex; /* NEW */ flex-direction: column; /* NEW */}#number1 { position: absolute; font-size: 7.4300rem; z-index: 1;}#row-1 > div > h3,#row-1 > div > p { text-align: center; color: white; z-index: 99; margin-bottom: 0; }
<div id="row-1" class="row"> <div> <span id="number1">01</span> <h3>This is A Title</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <div> <h3>This is A Title</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div> <div> <h3>This is A Title</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.</p> </div></div>
flex items and negative z-index numbers
An element can be placed directly behind its parent div
, even if the parent is a flex-item. Albeit we have to take care of three players:
The flex container: Must have a
position
(not static, of course) and az-index
.The flex item: Should have a
position
, but MUST NOT have az-index
.The child behind: Must have a
position
andz-index:-1
Try it in this JSFiddle
We can even finetune the appearance of the child behind:
- Child shall appear directly behind the flex item, but above the flex container: Apply any z-index to the flex container, but none to the flex item.
- Child shall appear behind the flex group (behind the flex item and behind the flex container): Do not apply z-index to flex container nor flex item.
Update: As turned out in the discussion (see question comments, if interested), this behaviour and solution is not limited to flex. Nevertheless, it will occur especially there as flexbox is a 2-tier structure itself (flex container > flex item > child behind).
Why does z-index not work with display: flex; and a negative margin?
You need to use position: relative
to make z-index
behave like you want it to.
.small-text { margin-bottom: -20px; position: relative; z-index: 1;}
.small-text span { background-color: orange;}
.big-container { display: flex; align-items: center; background-color: purple;}
.big-text { display: flex; flex-direction: column; align-items: center;}
.big-text span { margin-top: 50px; background-color: lime;}
<div class="small-text"> <span>I want to select/highlight this.</span></div><div class="big-container"> <div class="big-text"> <span>But this element's margin is covering it up.</span> </div></div>
Does 'position: absolute' conflict with Flexbox?
No, absolutely positioning does not conflict with flex containers. Making an element be a flex container only affects its inner layout model, that is, the way in which its contents are laid out. Positioning affects the element itself, and can alter its outer role for flow layout.
That means that
If you add absolute positioning to an element with
display: inline-flex
, it will become block-level (likedisplay: flex
), but will still generate a flex formatting context.If you add absolute positioning to an element with
display: flex
, it will be sized using the shrink-to-fit algorithm (typical of inline-level containers) instead of the fill-available one.
That said, absolutely positioning conflicts with flex children.
As it is out-of-flow, an absolutely-positioned child of a flex
container does not participate in flex layout.
Related Topics
CSS - Inline Elements Ignoring Line-Height
CSS Calc Not Working in Safari and Fallback
Overflow Behavior After Using CSS3 Transform
Use Multiple @Font-Face Rules in CSS
Flexbox - Fill Remaining Space
Putting an Image Background Onto a CSS Triangle
How to Set Background-Color on 50% of Area CSS
Multiple Distinct Pages in One HTML File
How to Write Text on a HTML5 Canvas Element
How to Color Text in Github's Flavoured Markdown
How to Set Favicon.Ico Properly on Vue.Js Webpack Project
Make Input Type="Password" Use Number Pad on Mobile Devices
Square Div Where Height Is Equal to Viewport
Html/Css: Empty Page + Only Header Page When Printing Table