2

I'm trying to see if it's possible to have elements interwoven. I have a feeling it's not even possible. The only caveat to the solution is that b is a child element to a, d is a child element to c, and a and c are siblings (pretty much the html cannot change to to business rules).

Html

<div style="position:relative;margin-top: 50px">
    <div class="z a">
        <div class="z b"></div>
    </div>
    <div class="z c">
        <div class="z d"></div>
    </div>
</div>

CSS

.z{ position: absolute }
.a{ left: 10px; right: 10px; top: 10px; height: 50px; background-color: blue;}
.b{ left: 50px; right: 50px; top: 10px; height: 50px; background-color: red;}
.c{ left: 20px; right: 20px; top: 30px; height: 50px; background-color: green;}
.d{ left: 10px; right: 10px; top: 10px; height: 50px; background-color: purple;}


.a{ z-index: 1;}
.b{ z-index: 2;}
.c{ z-index: 1;}
.d{ z-index: 2;}

JsFiddle Example

Actual Result:

Incorrect Result

Expected Result:

Correct Result

Erik Philips
  • 53,428
  • 11
  • 128
  • 150
  • 2
    Read http://philipwalton.com/articles/what-no-one-told-you-about-z-index/ for some great explanation on z-index – ckuijjer Dec 12 '14 at 19:14

1 Answers1

3

z-index property sets the stack level of an element, relatively to the stacking context it belongs to.

Therefore, if you want to mix (in z-axis) the children of different elements, these parents must not establish any stacking context. This way the children will belong to the same stacking context, and you will be able to use z-index to order them in z-axis.

See Which CSS properties create a stacking context? to know how to prevent an element from establishing a stacking context. Among others, it needs the default position: static or z-index: auto, and opacity: 1.

In your case, .b belongs to a stacking context with z-index: 1. Then, it is overlapped by the contents of following stacking context with z-index greater or equal to 1, like .c. Setting a higher z-index to .b won't prevent that. And if you used a lower z-index on .c, then its contents like .d wouldn't be able to overlap .b.

Instead, removing the following will suffice:

.a { z-index: 1; }
.c { z-index: 1; }

This way, .a and .c won't generate any stacking context, so you will be able to order their children like you want.

.z{ position: absolute }
.a{ left: 10px; right: 10px; top: 10px; height: 50px; background-color: blue; }
.b{ left: 50px; right: 50px; top: 10px; height: 50px; background-color: red; }
.c{ left: 20px; right: 20px; top: 30px; height: 50px; background-color: green; }
.d{ left: 10px; right: 10px; top: 10px; height: 50px; background-color: purple; }

.b{ z-index: 2; }
.d{ z-index: 2; }
<div style="position:relative;margin-top: 50px">
  <div class="z a">
    <div class="z b"></div>
  </div>
  <div class="z c">
    <div class="z d"></div>
  </div>
</div>
Community
  • 1
  • 1
Oriol
  • 274,082
  • 63
  • 437
  • 513
  • I actually needed the z-indexing on the parent elements as well, but this still answers that requirement as well (which is that it can't work with parent elements with z-index's). – Erik Philips Dec 12 '14 at 19:42