1

I am trying to better understand the CSS z-index property and stacking contexts.

As practice, I've built a little HTML demo containing some elements, and I am trying to order them in all kinds of different orders using z-index positioning only.

The basic demo is available below, or in this fiddle.

#d1 { /*z-index: ;*/ position: relative; }
#d2 { /*z-index: ;*/ position: relative; }
#d3 { /*z-index: ;*/ position: relative; }
#d4 { /*z-index: ;*/ position: relative; }

#d1, #d2 {
  width: 500px;
  height: 200px;
}

#d3, #d4 {
  width: 300px;
  height: 150px;
}

#d1 {
  background-color: rgba(100,100,100,.6);
}

#d2 {
  background-color: rgba(0,255,0,.6);
  margin-top: -20px;
  margin-left: 20px;
}

#d3 {
  background-color: rgba(255,0,0,.6);
  margin-top: 70px;
  margin-left: 50px;
}

#d4 {
  background-color: rgba(0,0,255,.6);
  margin-top: -70px;
  margin-left: 150px;
}
<body>
  <div id="d1">#d1
    <div id="d3">#d3</div>
  </div>
  <div id="d2">#d2
    <div id="d4">#d4</div>
  </div>
</body>

Now, is it possible to stack the elements in the above demo in the following order (farthest to closest): #d1, #d4, #d2, #d3 ?

(To clarify, the order in the initial demo is: #d1, #d3, #d2, #d4)


Disclaimer:

Prior to asking this question, I have actually searched and read about z-index and stacking contexts. I am familiar with the general rules and specification of how z-index works, and when stacking contexts are created.

Hence, this is not a general "I do not understand how z-index works" question, and therefore it is not a duplicate of this question.

This question refers to the specific case that I have presented above in as much detail as I could. What I ask for is a very specific answer to that specific question - either "Yes, this can be done like so...", or "No, this can't be achieved, because..."

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Johan Hirsch
  • 557
  • 4
  • 21

3 Answers3

2

Now, is it possible to stack the elements in the above demo in the following order (farthest to closest): #d1, #d4, #d2, #d3 ?

No, it is not possible. The farthest you can go is #d1, #d4, #d2 with the following:

#d1 { z-index: -1; position: relative; }
#d2 {  }
#d3 {  }
#d4 { z-index: -1; position: relative; }

... but this results in #d1 creating a stacking context for #d3, which prevents #d3 from ever being painted above #d2 or #d4 because the negative z-index of #d1 causes #d1 itself to be painted below #d4 (as two boxes with the same stack level will be painted in source order, and #d4 comes after #d1) and #d2.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
1

In short, no. not without changing your HTML - but I assume from your question that it's the CSS you're trying to understand.

z-index of a child is tied to the z-index of the parent. You can change the layers of D1 and D2 and switch them front and back. But the child of D2 will share that layer. Like this:

D1 {z-index:1} // bottom layer
  child1{z-index:100}
  child2{z-index:2000}
D2 {z-index: 2}
  child1{z-index:3}
  child2{z-index:50} // top layer

Note that D1:child2 has an index of 2000 but will appear behind D2:child1 even though that has an index of 3.

Mark
  • 209
  • 1
  • 4
0

You must set height z-index for element you want to be above, if I understand correctly your question. For example:

#d4 {
    z-index: 10;
}
#d3 {
    z-index: 9;
}

id d4 will be about d3.

Z-index also support negative values. Other important note is the DOM element will be in directly report with parent. So if a child has z-index: 999 his parent z-index: 10, and sibling of his parent 15, child will not be over parent sibling.

Carnaru Valentin
  • 1,690
  • 17
  • 27