0

Consider a situation like:

<div id="one"/>
<div id="two">
   <div id="three"/>
</div>
<div id="four"/>

I'd like to give three a pseudoelement that appears behind it but in front of two (and any other ancestors if there were more). What's complicating this for me is that I'm using a UI framework that generates HTML and CSS so I can't do something specific for this one case -- it must work in general. The framework generates divs that use absolute positioning so assume one, two, and four are absolutely positioned. Three and its pseudoelement could have different position values as long as they behave right.

z-index -1 on the pseudo works great locally, but makes it appear behind two. Okay, create a new stacking context on three by setting its z-index to 0 but that doesn't work right. I think I'm misunderstanding the whole stacking context thing.

If you wonder what I'm really doing, I'm trying to add rounded gradient border support to the framework.

zeromus
  • 93
  • 1
  • 4
  • 1
    Could you create a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), this is hard to follow. Can't you give `.two` a z-index of 1, `.three::before` a z-index of 2 and `.three` a z-index of 3? – sallf Jan 17 '20 at 03:56
  • Here's a fiddle to play around with: https://jsfiddle.net/36p4d21h/ That doesn't appear to work. Also, ideally, I wouldn't have to go up and down the tree modifying multiple z-indices. I just may have to suck it up and use a extra real div. – zeromus Jan 17 '20 at 06:13

1 Answers1

0

Ah, your jsfiddle is much clearer. You can achieve this by giving your pseudo element a negative z-index.

Note that your div#three needs to keep the default z-index auto. If you apply an integer to it, it will create a new stacking context, and since it would be the base of that stacking context, no child element would be able to fall behind.

z-index is actually a little less straightforward than most people think. Here's a great article if you're interested.

PS divs are not self closing, so be sure to write a proper closing tag.

div {
  width: 100px;
  height: 100px;
  position: absolute;
}

#one {
  top: 0px;
  left: 0px;
  background: red;
}

#two {
  top: 20px;
  left: 20px;
  background: green;
  z-index: 1;
}

#three {
  top: 40px;
  left: 40px;
  background: lightblue;
}

#three::before {
  position: absolute;
  width: 200px;
  height: inherit;
  background: orange;
  content: '3 before';
  top: -20px;
  left: -20px;
  z-index: -1;
}
<div id="one">1</div> 
<div id="two">
  2
  <div id="three">3</div>
</div>
sallf
  • 2,583
  • 3
  • 19
  • 24