Flexbox, Z-Index & Position: Static: Why Isn't It Working

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
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.

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:

  1. The flex container: Must have a position (not static, of course) and a z-index.

  2. The flex item: Should have a position, but MUST NOT have a z-index.

  3. The child behind: Must have a position and z-index:-1

Try it in this JSFiddle

We can even finetune the appearance of the child behind:

  1. 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.
  2. 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 (like display: 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



Leave a reply



Submit