18

I would like to know if it possible to have a child element behind his parent element with z-index.

I would like to use the parent div as transparent color layer on top of his content.

TylerH
  • 20,799
  • 66
  • 75
  • 101
Roch
  • 21,741
  • 29
  • 77
  • 120

5 Answers5

20

Why not? Sure you can, and it's easy:

  1. give a non-static position to your desired elements;
  2. set z-index of child to -1;
  3. create a stacking context on the main container (by setting on it a z-index, opacity, transforms or whatelse generates a composite layer).

.container {
    position: absolute;
    z-index: 0; /* or eg. opacity: 0.99;*/
  
    background-color: blue;
    color: lightblue;
    width: 100%;
    height: 100%;
    text-align: center;
}

.parent {
    position: relative;
  
    background-color: rgba(100, 255, 150, 0.75);
    color: green;
    width: 50%;
    height: 30%;
    top: 30%;
    left: 20%;
}

.child {
    position: absolute;
    z-index: -1;
  
    background-color: orange;
    color: yellow;
    width: 100%;
    height: 100%;
    top: -50%;
    left: 20%;
}
<div class="container">
    <span>container</span>
    <div class="parent">
        <span>parent</span>
        <div class="child">
            <span>child</span>
        </div>
    </div>
</div>

(if the parent is used as a transparent layer, be sure to use a background-image or rgba background-color: children inherit the opacity of the parent)

Saurav Rastogi
  • 9,575
  • 3
  • 29
  • 41
guari
  • 3,715
  • 3
  • 28
  • 25
  • 3
    This is the best answer. Also this doesn't work if the `.parent` has a fixed position, make it absolute if you can instead. – Martin Dawson Jan 22 '17 at 20:33
  • 8
    Your answer is great and I've upvoted it; one quibble: avoid ever saying 'it's easy' in explanations. If something is truly easy, it wouldn't need explaining, right!? In this context there's probably a deep wealth of CSS knowledge that you are deploying that you've forgotten that you possess! Reading 'it's easy' when you don't know something yet just makes the reader feel needlessly stupid. – EoghanM Jan 11 '19 at 17:47
  • But the `z-index: -1` solution does not really hide it behind the parent, it hides it behind all the content. It only works with `-1`. If you give the parent a positive index and the child `0`, it wont work. For example, I need my child to be displayed behind its container, but still in front of other content. Is that possible? – Bexy-Lyn Jun 25 '22 at 19:53
  • `z-index: -1` places the child layer behind the parent layer, when they are in the same stacking context. If you give the parent a z-index then you're creating a new nested stacking context on the parent itself and you can't move the child behind. – guari Jul 01 '22 at 15:28
  • This will not work if the parent has a z-index itself. – Lumnezia Aug 18 '22 at 08:53
  • Yes you have to understand how stacking context works :) By setting on the parent layer one of the CSS properties that creates a new stacking context (`z-index`, `transform`, `opacity`, `position: fixed`, `will-change`, etc.), this layer will be promoted to the gpu, at that point you will not be able to move one of its child layers behind it, or in other words, you will not be able to render a nested element outside of that stack. This is one of the key concepts behind CSS rendering engines and composite layers. – guari Aug 25 '22 at 15:08
7

The short answer is Yes ;) There is an excellent article here that describes how you can use the stacking order of elements to allow the z-index to be negative in order to place an element behind it's parent.

http://philipwalton.com/articles/what-no-one-told-you-about-z-index/

David Newcomb
  • 10,639
  • 3
  • 49
  • 62
1

While this wouldn't necessarily work in all browsers (especially older ones), the following has worked for me in the past:

#child {
  position: relative;
  z-index: -1;
  ...
}

I'm really only suggesting this as a last resort and would still prefer to use any technique other than this, although it might be ideal in your scenario.

WynandB
  • 1,377
  • 15
  • 16
  • I understand it works. I can see it works but I do not understand HOW it works. From what I have read so far on this topic, when you set a position (absolute or relative) on an element AND you also set its z-index value to anything other than 0, it creates a new stacking context. In this case, clearly a new stacking context has been created on child. My question how does it go below the parent element? – Haris Ghauri Apr 25 '19 at 01:25
1

Not possible, because each positioned element creates a stacking context.

Explanation 1, Explanation 2

Strelok
  • 50,229
  • 9
  • 102
  • 115
1

You could just do it the other way and use the child as the overlay like this

HTML

<div id="stuff"><div class="overlay"></div>
    <p>
    Cras venenatis ornare tincidunt. Nam laoreet ante sed nibh pretium nec gravida turpis dapibus. Curabitur lobortis; lacus sit amet rutrum aliquet, est massa feugiat lectus, bibendum eleifend velit metus vitae dolor! Duis vulputate mi vitae quam fermentum pharetra.
    </p>
</div>

CSS

#stuff{
    position:relative;
    }

.overlay{
    width:100%;
    height:100%;
    position:absolute;
    top:0;
    left:0;
    background:#ACA;
    opacity:0.4;
    }
Gilsham
  • 2,276
  • 2
  • 13
  • 14