22

In CSS 2.1, z-index only applies to positioned elements, and specifies two different things:

  1. The stack level of the box in the current stacking context.
  2. Whether the box establishes a stacking context.

But Flexbox says this:

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.

Then, unlike CSS2.1, setting z-index to some integer on a non-positioned flex item creates a stacking context.

However, I don't see defined anywhere which should be the stack level of this stacking context.

A similar case is opacity, which can also create establish stacking contexts on non-positioned elements. But in this case the stack level is properly specified to be 0:

If an element with opacity less than 1 is not positioned, implementations must paint the layer it creates, within its parent stacking context, at the same stacking order that would be used if it were a positioned element with z-index: 0 and opacity: 1.

In my opinion these options are reasonable:

  • The stack level is the value specified in z-index
  • The stack level is 0
  • The flex item wraps its descendants in a stacking context so that they are painted together, but the flex item itself is painted as a normal in-flow non-positioned elements (as if it didn't establish an stacking context).

According to the following test, both Firefox and Chrome do the first option.

.container {
  display: flex;
  padding-left: 20px;
}
.item {
  padding: 20px;
  background: #ffa;
  align-self: flex-start;
  margin-left: -20px;
}
.item:nth-child(even) {
  background: #aff;
  margin-top: 40px;
}
.za::after{ content: 'z-index: auto'; }
.z0 { z-index: 0; } .z0::after{ content: 'z-index: 0'; }
.z1 { z-index: 1; } .z1::after{ content: 'z-index: 1'; }
.z-1 { z-index: -1; } .z-1::after{ content: 'z-index: -1'; }
<div class="container">
  <div class="item z1"></div>
  <div class="item z0"></div>
  <div class="item za"></div>
  <div class="item za"></div>
  <div class="item z-1"></div>
</div>

Is this behavior defined somewhere?

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • An intriguing question raised by your question and, in particular, your snippet is: *How is `z-index` working without the `order` property?* The spec clearly says the document order has to be *`order`-modified*, but you were able to control the layering of your divs without `order` anywhere in the code. – Michael Benjamin Jan 02 '16 at 22:42
  • @Michael_B That's not the way I read the spec...it's just detailing the differences...not saying that `order` is required to establish `z-index`. – Paulie_D Jan 02 '16 at 22:45
  • @Paulie_D, then I must have made a mistake [**here**](http://stackoverflow.com/q/33391370/3597276), because I couldn't get `z-index` to work without the `order` property. – Michael Benjamin Jan 02 '16 at 22:47
  • Perhaps so...clearly it is possible from Oriol's demo. I've checked the spec and I can only find the single reference to z-index as mentioned above. I guess the default stack level isn't defined just that a stack is created. – Paulie_D Jan 02 '16 at 22:53
  • @Michael_B In my understanding, the sentence in the spec means that boxes with the same stack level are painted back-to-front according to `order` (outside flexbox it would be document tree order). – Oriol Jan 02 '16 at 22:56
  • When I answered [that question](http://stackoverflow.com/q/33391370/3597276) 2 months ago I spent about 30 minutes trying to figure out why `z-index` wasn't working on the flex items. It wasn't until I tried `order` (with a helpful nudge [from this post](http://stackoverflow.com/q/27484191/3597276)), that everything fell in place. Up until that point, the spec language itself wasn't entirely clear to me. – Michael Benjamin Jan 02 '16 at 23:04
  • 1
    @Michael_B In fact I saw your answer and thought that `order` seemed unnecessary in case `z-index` determined the stack level in non-positioned flex items, but otherwise either `order` or positioning were necessary. So I asked this question to know which should be the case. Thanks for making me think about this part of the spec. – Oriol Jan 02 '16 at 23:15
  • 1
    @BrettDeWoody Thanks, I wanted to start a bounty myself but forgot. Hopefully it will attract Xanthir, dholbert or someone with great knowledge about flexbox. – Oriol Feb 03 '16 at 15:30
  • I don't see why CSS2.1 would not apply here. At the very least, that's what Firefox and Chrome seem to be doing. (I can't comment on how the `order` property affects this.) – BoltClock Feb 03 '16 at 15:38
  • @BoltClock The problem is that CSS2.1 says that `z-index` does not apply to non-positioned elements. And [Elaborate description of Stacking Contexts](https://www.w3.org/TR/CSS21/zindex.html) does not consider non-positioned stacking context. – Oriol Feb 03 '16 at 15:48
  • @Oriol: Oh, right, I forgot. – BoltClock Feb 03 '16 at 15:49
  • @Oriol, not sure 50 rep points will bring any big names out of hiding ;-) You may just want to ping them directly. – Michael Benjamin Feb 03 '16 at 18:24
  • @Michael_B Starting a bounty worked [here](http://stackoverflow.com/q/31094454/1529630), though :) And [pinging directly is not appreciated](http://meta.stackoverflow.com/q/309690/1529630). – Oriol Feb 03 '16 at 19:13
  • @Oriol, not to make this a big deal, but the bounty example could have been luck, or even a question he would have answered regardless of bounty. The second point, about *not appreciated*, is highly subjective. Some people may not appreciate a special request for an answer. Others may be flattered by the request, and happy to oblige. Trust me, if ever I need an answer to a difficult question, you can expect a ping from me ;-) You can always just ignore it. – Michael Benjamin Feb 03 '16 at 19:20
  • 1
    @Michael_B Hopefully the bounty will attract somebody who can answer, even if it's not somebody involved in the spec (that would require lots of luck, yes). I don't mind being pinged if the question is interesting – Oriol Feb 03 '16 at 20:27
  • 1
    @Oriol I remember tweeting Tab directly asking if he could answer that question, sorry to rain on your bounty theory :-) but that was sort of a unique case that kind of *required* a WG member to answer. This one may actually a similar case, though... – TylerH Feb 04 '16 at 01:12
  • @TylerH Good to know XD thanks – Oriol Feb 04 '16 at 01:19
  • @Oriol [Tweet in question](https://twitter.com/Tyler_Hibbard/status/615969917179928577) – TylerH Feb 04 '16 at 01:24
  • 1
    Seems like a few tweets might be what we need @Michael_B :) – Brett DeWoody Feb 04 '16 at 02:17

1 Answers1

6

CSS Working Group:

The CSSWG couldn't think of a good reason to make flex items establish pseudo-stacking contexts, so we have resolved to treat them the same way as block and table cell elements.

source: https://lists.w3.org/Archives/Public/www-style/2012Jul/0382.html

More information:


Also, although not a direct answer to the question, the following W3C Editor's Drafts provide strong hints as to where CSS is going with z-index and stacking contexts.

11. Layered presentation ~ CSS Positioned Layout Module Level 3

12. Detailed stacking context ~ CSS Positioned Layout Module Level 3

4.3. Z-axis Ordering: the z-index property ~ CSS Grid Layout Module Level 1

It's interesting to note that z-index, as currently defined in the CSS Positioned 3 Editor's Draft, applies only to positioned elements. This is no different than CSS 2.1. Yet grid items and flex items can both create stacking contexts with z-index, even when position is static.

Michael Benjamin
  • 346,931
  • 104
  • 581
  • 701
  • 1
    The [first version of the spec](https://www.w3.org/TR/2012/CR-css3-flexbox-20120918/#painting) that mentions z-index and stacking on the vertical plane appears to be newer than those Working Group conversations. That could be strong evidence that they changed their mind; as I understand it, these drafts (in any state) take precedence over mailing list conversations. – TylerH Feb 04 '16 at 01:17
  • There is good info in those threads, thanks. I will read them thoroughly tomorrow. The concept of pseudo stacking context seems useful, I wonder why they didn't use it in CSS2.1 nor CSS3-Positioning – Oriol Feb 04 '16 at 01:43
  • 1
    The quote from [CSS Grids](https://drafts.csswg.org/css-grid/#z-order) is interesting: "*values other than auto create a stacking context even if position is static. **Thus** the z-index property can easily be used to control the z-axis order of grid items.*". The "thus" seems to mean that the second sentence is only a clarification, and z-index can always (not only in grids) control the z-axis order of stacking contexts, even if CSS Positioned doesn't seem to say this. Then it would apply to non-positioned flex items with z-index. – Oriol Feb 04 '16 at 21:26