Do floated elements create a separate stacking con

2019-03-17 23:40发布

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.

1条回答
乱世女痞
2楼-- · 2019-03-18 00:14

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;
}
查看更多
登录 后发表回答