26

I've created a 'header' element with a before-pseudo element. the pseudeo element must be behind the parent element. Everything works great till the moment I give my 'header' a z-index.

What I want: The yellow 'header' on the foreground, the red pseudo-element in the background and a simple z-index of 30 on the yellow 'header' element.

header { 
    background: yellow;
    position:relative;
    height: 100px;
    width: 100px;
    z-index:30; /*This is the problem*/
}

header::before { 
    content:"Hide you behind!";
    background: red;
    position:absolute;
    height: 100px;
    width: 100px;
    top:25px;
    left:25px;
    z-index:-1;
}

You can test my problem on this link (http://jsfiddle.net/tZKDy/) and you see the problem when you set/remove the z-index on de 'header' element.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
Tom Claus
  • 1,301
  • 1
  • 9
  • 13
  • "What I want: The yellow 'header' on the foreground, the red pseudo-element in the background and a simple z-index of 30 on the yellow 'header' element." ... "Everything works great till the moment I give 'my header" a z-index" it sounds like what you want occurs when the z-index is applied. what's wrong with the z-index being applied? – albert Oct 19 '11 at 14:56

2 Answers2

34

The ::before pseudo-element is placed inside the header element.

CSS Spec:

The :before and :after pseudo-elements interact with other boxes as if they were real elements inserted just inside their associated element.

Setting the z-index for the header element creates a new Stacking Context, so the new pseudo element you created can not float behind the header element, because it would have to go outside that Stacking Context.

I suggest that you simply precede the header element by another element, so it stacks correctly by default. Example.

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
RC-1290
  • 595
  • 6
  • 10
  • 2
    Unfortunately, the Example is broken: the CSS is missing a closing brace in the first rule. I [forked and fixed](http://jsfiddle.net/dland/xs2b68ub/2/) it. – Dave Land Apr 08 '15 at 22:39
  • I think this is not a good solution because I can't see the point in using a relative-absolute positioning, while in fact they are not positioned relatively. Adding a `left:50px` for instance breaks it. – aderchox Mar 22 '20 at 02:25
1

I used z-index:-1 (enter link description here)

a {
    position: relative;
    z-index: 1;
    text-align: center;
    display: table-cell;
    vertical-align: middle;
}

a::before {
    content: "";
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    background-color: yellow;
    z-index: -1;    
}
Timo Tijhof
  • 10,032
  • 6
  • 34
  • 48
  • 2
    Welcome to Stack Overflow. Your answer looks like its using a CSS Preprocessor, presumably SCSS, but the original question only makes use of CSS. Could you clarify in your answer or format it as CSS? – Aonghas M Mar 10 '20 at 11:59
  • This works only in relation to the nodes inside the target element ( e.g. the text ). The before element will still always overlap the background of the target element (so you can't overlay the before element with a gradient in the background-image for example). – Excalibaard Mar 14 '22 at 10:10