Search code examples
htmlcssz-indexoverlap

Why does text on the same layer overlap - even when it has an opaque background?


I know that I can stack elements in separate layers by creating new stacking contexts with relative/absolute positioning (Demo) or opacity (Demo)

However I was under the impression that by default an element further down in the html will be painted above previous elements.

Apparently, this is so for the element's background, but I just noticed that text works differently.

So with simple markup like:

<div class="div1">text1</div>
<div class="div2">text2</div>

The background of the 2nd div will be above the first, but the text overlaps.

.div1,
.div2 {
  width: 200px;
  height: 150px;
  overflow: hidden;
  color: white;
}
.div1 {
  background: maroon;
}
.div2 {
  background: green;
  margin: -100px 0 0 100px;
}
<div class="div1"></div>
<div class="div2"></div>
<hr />
<div class="div1">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
  survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
  software like Aldus PageMaker including versions of Lorem Ipsum.</div>
<div class="div2">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
  survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
  software like Aldus PageMaker including versions of Lorem Ipsum.</div>

Demo

enter image description here

Must I create a new stacking context to prevent the text overlapping here?


Solution

  • Why does text on the same layer overlap - even when it has an opaque background?

    The spec says (emphases mine):

    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).

    The backgrounds and the text are considered separately in the painting order: the backgrounds are represented by #3, and the text is represented by #5. The second element appears later in the source, so it is painted over the first, but the text still needs to be painted over the backgrounds, because the two elements are participating in the same stacking context.

    Must I create a new stacking context to prevent the text overlapping here?

    Yes, the best way to deal with this is by positioning the elements or by having them establish their own stacking contexts. A stacking context is always self-contained, so having each element establish its own stacking context will always ensure that the backgrounds and text of the two elements don't overlap one another.