5

Given the following HTML:

<div class="foo">howdy howdy howdy how</div>
<div class="bar">Hello</div>​

and the following CSS:

.foo {
    background-color:green;
    overflow:hidden;
    height:.75em;
}

.bar {
    color: white;
    background-color: red;
    margin-top: -10px;
    width: 200px;
}

The layer order is something like this:

weird layer order

Here's the associated jsfiddle: http://jsfiddle.net/q3J8D/

I would expect the red background to be on top of the black text and don't understand why the black text is on top of the red background.

I can fix this problem using position: relative, but I'm just curious.

Why is the black text on top of the red background?

I'm particularly looking for an official source/standard that explains this behaviour.

Jamie Wong
  • 18,104
  • 8
  • 63
  • 81

2 Answers2

3

It took me a while to understand it, even after reading the spec multiple times, and BoltClock's answer to the linked question.

But it seems the explanation is simple: since these are two static (i.e. non-positioned), block-level elements inside the same stacking context (the root context), they are drawn in the following order:

  • background of #foo
  • background of #bar
  • text content of #foo
  • text content of #bar

Thus, the output we see in the question.

The paint order is dictated by an algorithm described in Appendix E of the CSS 2.1 spec. What is not in the appendix (but is mentioned here), is that the algorithm is applied recursively for each stacking context (not each element).

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
  • The root stacking context is `html`, not `body`. Besides that, you basically got it. Nicely done :) – BoltClock Jun 20 '12 at 22:18
  • @BoltClock So the `body` is creating a new stacking context too? I thought not. BTW: sorry if I wasted your time asking for help. I got somewhat obsessed about this question. The last sentence in my answer explains the source of all my confusion. – bfavaretto Jun 20 '12 at 22:21
  • `body` doesn't create a new stacking context, but as a child of `html`, it's painted on top of `html`, followed by the two `div`s. I suppose that comment was for clarification for the OP and other readers, more than anything. And no worries, no time wasted - I figured you were working on it anyway. – BoltClock Jun 20 '12 at 22:23
  • Also note that the "text content" is represented as anonymous inline boxes with respect to the algorithm. – BoltClock Jun 20 '12 at 22:26
  • Yeah, that's where I got lost: step `7.2.1.4.1.1` :). And thanks for the edit. – bfavaretto Jun 20 '12 at 22:30
  • Thanks! I never knew the paint order is so complicated. This seems really counterintuitive to me - can you think of an example where this behaviour is more intuitive than the behaviour I was expecting? – Jamie Wong Jun 21 '12 at 15:58
  • @JamieWong I agree it's not intuitive. Maybe they defined it this way based on the "normal" flow of elements, where they never overlap - unless they are positioned, in which case the paint order is different (as you noticed when you added `position: relative`). Negative margins are basically a hack - often necessary to create cross-browser CSS layouts, and perhaps they weren't paying much attention to that when the paint order algorithm was created. Who knows? – bfavaretto Jun 22 '12 at 01:52
  • Negative margins aren't a hack *per se*, but I wouldn't blame the working group for overlooking them while working on the painting algorithm :) – BoltClock Jun 23 '12 at 06:25
-1

http://www.w3.org/TR/CSS21/visuren.html#z-index

"This example demonstrates the notion of transparency. The default behavior of the background is to allow boxes behind it to be visible. In the example, each box transparently overlays the boxes below it. This behavior can be overridden by using one of the existing background properties"

Tony318
  • 552
  • 2
  • 9