5

#twitter{
  width:50px;
  height:50px;
  position: absolute;
  right: 0%;
  bottom: 0%;
  background-color: orange; 
  z-index:-2;
}

#socialButton {
  position: relative;
  width: 80px;
  height: 80px;
  background-color: green;
  z-index: 2;
}

#socialButtonRoot {
  width: 100px;
  height: 100px;
  top:20%;
  left:20%;
  position: absolute;
  background-color: hotpink;
  z-index: 5;
}
<div id="socialButtonRoot">
  <div id="socialButton">
    <div id="twitter"></div>
  </div>
</div>

This is a simplified version.

In my react project there's component created some Dom nodes, after that I set the styles for them in the CSS file, most styles works fine, but only the z-index style doesn't work, people said we should set the position, yes I've all of them set, but it still doesn't work. So I think it maybe something to do with React or JS, but after I extracted code from React and JS and test it on jsfiddle, z-index still doesn't work. Then, I changed changed the z-index value from 2 to "2" (a string ) , it works, but I can see the value "2" is invalid in the chrome's debug console.

It should be div socialButtonRoot on the front which have highest z-index(5) and div socialButton in the middle which have the second high z-index(2) and div twitter in the back, which have the lowest z-index.

but in the result below, it shows, div twitter on the front and div socialButton in the middle and div socialButtonRoot on the back, which isn't right.

What's the problem here?

cary
  • 148
  • 2
  • 7

2 Answers2

7

See The Stacking Context on MDN.

A stacking context is formed, anywhere in the document, by any element in the following scenarios: … Element with a position value "absolute" or "relative" and z-index value other than "auto".

Within a stacking context, child elements are stacked according to the same rules previously explained. Importantly, the z-index values of its child stacking contexts only have meaning in this parent. Stacking contexts are treated atomically as a single unit in the parent stacking context.

The z-index positions an element inside the stacking context it is associated with.

Giving an element position: absolute or position: relative establishes a new stacking context.

Thus #twitter is positioned inside the 3-d box represented by #socialButton.

The z-index is for that box, and not for the entire document.

(And #socialButton is inside #socialButtonRoot in the same way).


If you want A to be rendered below B then either:

  • Do not position A or
  • Do not make B a descendant of A
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • It worked, thank you~ – cary Aug 07 '18 at 07:59
  • There is a particular case where the element can be positioned and the z-index will work ... The positioned element will create a stacking context BUT their child will not belong to it but to the upper one : https://stackoverflow.com/a/51603436/8620333 – Temani Afif Aug 07 '18 at 09:09
0

When you place an element inside another element, The child element will display on top of its parent element. This is the same for many nested elements and is the default CSS behaviour. Even setting a higher z-index for the parent than its child element won't change the result. In your example:

<div id="socialButtonRoot">
  <div id="socialButton">
    <div id="twitter"></div>
  </div>
</div>

#socialButtonRoot will be displayed at the bottom. #socialButton will display on top of #socialBuuttonRoot. On top of all, #twitter will show. The z-index will be ignored as it only affects elements of the same level.

I suggest you create a parent <div> and place all three <div>s inside:

#parent {
  position: relative;
  width: 100px;
  height: 100px;
  margin-top: 20vh;
  margin-left: 20vw;
}

#socialButtonRoot {
  position: absolute;
  width: 100px;
  height: 100px;
  z-index: 5;
  background-color: hotpink;
}

#socialButton {
  position: relative;
  width: 80px;
  height: 80px;
  z-index: 2;
  background-color: green;
}

#twitter {
  position: absolute;
  width: 50px;
  height: 50px;
  right: 20%;
  bottom: 20%;
  background-color: orange;
  z-index: -2;
}
<div id="parent">
  <div id="socialButtonRoot"></div>
  <div id="socialButton"></div>
  <div id="twitter"></div>
</div>

I used position:relative for the parent <div> so that I can position the children <div>s using percentages. I also used margin-top and margin-left instead of top and left respectively, since the latter don't work with relatively positioned elements.

Since #socialButtonRoot is the largest <div> and is placed in front of the other two, it is the only one that appears when you run the snippet. You can change the z-index for each <div> as you wish

Wais Kamal
  • 5,858
  • 2
  • 17
  • 36