Clarification Stacking_and_float

Hello guys, I need a help with the stacking_and_float topic: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Positioning/Understanding_z_index/Stacking_and_float => In this section it is mentioned the next note:
Note: In this example, all the blocks except the non-positioned one are translucent to show the stacking order. If the opacity value of the non-positioned block (DIV #4) is changed, then something strange happens: the background and border of that block pops up above the floating blocks and the positioned blocks. This is due to a peculiar part of the specification: applying a opacity value creates a new stacking context (see What No One Told You About Z-Index).”

However, even though div4 creates a stacking context with opacity <1, why does it stack on top of positioned and floated elements? the specification mentions that positioned elements will be on top of unpositioned ones and div4 is not positioned

Thank you

Hi @robertm,

This is because the opacity value puts the div into its own stacking context, separate from the other divs that all sit in another single stacking context.

The order list detailed on that page, and in the spec applies to elements inside the same stacking context, but separate stacking contexts appear above/below one another according to source order, IIRC.

Yes, of course I understand the fact that each one creates a stacking context, but keep in mind that these atomic stacking contexts belong to the global stacking context (html), so the stacking order would continue to apply:

  • root of stacking context
  • stacking contexts created with negative z-index
  • statically positioned elements (div4, although create your stacking context)
    -floats
    -elements positioned with z-index: auto (although they can create their stacking context with another property)
    -stacking contexts created by z-index> 0

Can you explain me best? I would thank you
Those div’s are in the global stacking context(html) and althought they create new stacking contexts, must be order with relation the rules in their parent stacking context

Heh, this is one of those horribly complicated parts of CSS that doesn’t matter most of the time. But it is certainly worth trying to understand what is going on.

The way I understand it is that the stacking contexts themselves don’t have positioning/floating applied to them; they just appear in front or behind one another based on their position in the source order. It is only when you have multiple elements in the same stacking context that these rules apply.

In the case of this demo, by default:

  • The non floated, non positioned div (4) sits at the back. It is not in its own stacking context, it sits in the global stacking context.
  • The floated divs (2 + 3) sit in the front of div 4. They don’t form their own stacking contexts, but they do sit in front of non-floated elements.
  • the positioned divs (1 + 5) form ther own stacking contexts, and sit in front of the global stacking context, in source order.

When you apply opacity < 1 to the non floated, non positioned div, it creates its own stacking context, so immediately jumps above the global stacking context, where divs 2 and 3 are.
but it also jumps above div 1. they are in their own stacking contexts, but div 4 is later in the source order.
However, div 4 does not jump above div 5, as div 5 also has its own stacking context, and is later in the source order. You can test this by giving div 4 opacity: 0.9, and making div 5’s top value smaller so that it sits over the top of div 4.

I hope this helps a bit. I stuggle with this some times, so it is useful for me to try and work it through in my head.

WOWW I think that now if I can better understand the context stacking on non-positioned elements and their stack level, thanks for the time you took to explain to me, I really appreciate it, I will continue reading the specification on w3c.org in the visual formatting model
I think I’m going well despite having only 4 months of css learning haha, saludos

You are welcome; I got there in the end! It took a while to work it through in my head; this is a really complex bit of CSS.