Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do floated elements create a separate stacking context like positioned ones do?

Recently I lit upon an interesting article about the CSS z-index property. I found it because I was seeking for an answer about why overflowed text from a preceding div was displayed above the background of a following div but not above the background of a span in the following div, like here (jsfiddle):

#overflowed {
  background-color: green;
  width: 300px;
  height: 100px;
}
#non-floated {
  background-color: pink;
  width: 300px;
}
#non-floated span {
  background-color: yellow;
}

an inline box inside a block box

The explanation for this is the fact that a browser draws elements in a specific order, which is based on the so-called stacking order:

the stacking order of a HTML/CSS layout in a browser

So for the root-element in a layout and every positioned element, the browser creates such stacking order and then draws all these orders in, sorry for the pun, the respective order.

So this is why inline elements and text (those which create inline boxes) are drawn above block level elements, even if these block elements appear later in a document, like in my jsfiddle above.


So the question itself.

I still cannot find an answer why these inline boxes, if they are created, for inline elements and text inside a floated element are not drawn with other inline boxes which are outside the floated element according the the scheme of the stacking order above, like here (jsfiddle):

#overflowed {
  background-color: green;
  width: 300px;
  height: 100px;
}
#floated {
  background-color: pink;
  width: 300px;
  float: left;
}
#floated span {
  background-color: yellow;
}

enter image description here

Here you can clearly see, that the text from the first div in the document, which is not floated, is drawn above (after) the span's yellow background, while the span is an inline element and according to the image of the stacking order above is supposed to be drawn after the floated container (its background and borders).

So does anyone have an proven explanation for this? I suppose that floated elements create something like their own stacking order, like positioned elements do, but I have not found any mention of this in the web yet.

like image 621
Dmitry Koroliov Avatar asked Jan 04 '16 08:01

Dmitry Koroliov


People also ask

What creates a new stacking context?

You can create a new stacking context by adding a value for properties which create a new composite layer such as opacity , will-change and transform .

Does position relative create a stacking context?

TLDR; elements with position: relative do not create a new stacking context, but get drawn on top of non-positioned elements (i.e. elements with position: static ) either way because they are positioned elements.

What does floating an element do?

The float CSS property places an element on the left or right side of its container, allowing text and inline elements to wrap around it. The element is removed from the normal flow of the page, though still remaining a part of the flow (in contrast to absolute positioning).

Which of these creates a stacking context in CSS?

The root element always holds a root stacking context. This is why you can start arranging elements without having to position the root element first.


1 Answers

CSS2.1 specifies the painting order of elements as follows:

Within each stacking context, the following layers are painted in back-to-front order:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

Floats do not establish stacking contexts on their own. They will only do so if they are positioned and have a z-index that is not auto (not counting any of the numerous other ways an element may do so). Otherwise, they participate in the same stacking context as other elements, including inlines, with the following caveat (from the same link above):

Within each stacking context, positioned elements with stack level 0 (in layer 6), non-positioned floats (layer 4), inline blocks (layer 5), and inline tables (layer 5), are painted as if those elements themselves generated new stacking contexts, except that their positioned descendants and any would-be child stacking contexts take part in the current stacking context.

Since all elements in your fiddle are participating in the same stacking context, and your floating element is not positioned (#4), the inline contents of the overflowing div (#5) are painted above the floating element and its descendant elements, even though the floating element appears later in source order.

The background of the overflowing div (#1) is painted below that of the float, however, because the background of the float is considered part of the float itself in accordance with the second quote above. You can see this by giving the float a negative margin:

#floated {
  background-color: pink;
  width: 300px;
  float: left;
  margin-top: -50px;
}
like image 133
BoltClock Avatar answered Nov 04 '22 12:11

BoltClock