0

I wish that in CSS the before will render before the container, and the after will render after. something like

before : z-index = 0, container: z-index = 1, and after: z-index = 2

but the order is before : z-index = 1, container: z-index = 0, and after: z-index = 2

HTML:

<div id=theDiv>DIV</div>

CSS:

#theDiv{
  position:relative;
  width:100px; height:100px;
  background-color:red;
  margin:50px;
}
#theDiv:before{
  content:"Before";
  position:absolute; top:-30px; left:-30px;
  width:90px; height:90px;
  background-color:blue;
}
#theDiv:after{
  content:"After";
  position:absolute; top:30px; left:30px;
  width:90px; height:90px;
  background-color:yellow;
}

https://jsfiddle.net/shprung/892y1gzc/

My usual solution is to force on the before a z-index of -1 which fill like a hack.

The specs don't mentioned the stacking order by indirectly suggests what I was hoping for :

...As their names indicate, the :before and :after pseudo-elements specify the location of content before and after an element's document tree content...

Any better solution than forcing the z-index:-1 ?

Other similar question want to assume that all you need is to setup new stacking content, but this is not the case. for example, if you give each a z-index like the code below it still not behave correctly. so the z-index:-1 for the before is some unique case and this is why I am puzzled.

#theDiv{
  z-index:50;
  position:relative;
  width:100px; height:100px;
  background-color:red;
  margin:50px;
}
#theDiv:before{
  z-index:1;
  content:"Before"; 
  position:absolute; top:-30px; left:-30px;
  width:90px; height:90px;
  background-color:blue;
}
#theDiv:after{
  z-index:100;
  content:"After";
  position:absolute; top:30px; left:30px;
  width:90px; height:90px;
  background-color:yellow;
}
Shai Shprung
  • 146
  • 8
  • Possible duplicate of [z-index of :before or :after to be below the element, Is that possible?](http://stackoverflow.com/questions/3032856/z-index-of-before-or-after-to-be-below-the-element-is-that-possible) – Daerik Dec 08 '16 at 20:38
  • 3
    It's not a hack, it's how it's designed to work. – junkfoodjunkie Dec 08 '16 at 20:41
  • 2
    `:before` renders before the _content_ of `#theDiv` not before the actual `div`. But yea, use `-1` for `z-index`, and you can also use `pointer-events: none` – powerbuoy Dec 08 '16 at 20:56

1 Answers1

4

::before and ::after create pseudo elements as children of the selected element, not as siblings. So adding a ::before and ::after to #theDiv is similar to creating:

<div id="theDiv">
    <span id="theDiv_before"></span>
    DIV
    <span id="theDiv_after"></span>
</div>

Child elements stack above parent elements, and that's why the pseudo elements display that way.

See this article on the stacking context in CSS for more information.

The solution would be to either create the pseudo elements on the container of your div or else keep using z-index: -1.

Confused One
  • 176
  • 4
  • 12