Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

z-index when using ::after under element

If we use z-index combined with position: absolute; its possible to place the ::before of a element under itself. There is a good example on another question (jsfiddle.net/Ldtfpvxy).

Basically

<div id="element"></div>

#element { 
    position: relative;
    width: 100px;
    height: 100px;
    background-color: blue;
}

#element::after {
    content: "";
    width: 150px;
    height: 150px;
    background-color: red;

    /* create a new stacking context */
    position: absolute;
    z-index: -1;  /* to be below the parent element */
}

renders:

enter image description here

So the stacking context/order is defined by z-index. But when I apply z-index: 1; to the element and z-index: -1; to its ::before I cannot achieve the same thing.

Only if I omit z-index from the element.

Any ideas why this is? Is the element rendered after its ::before & ::after pseudos so they get the same z-index?

Working: https://jsfiddle.net/Ldtfpvxy/
Not working: https://jsfiddle.net/Ldtfpvxy/1/ (only added z-index: 1; to element)

like image 961
Sergio Avatar asked Jul 09 '15 16:07

Sergio


People also ask

Does Z Index working on pseudo element?

To position a pseudo-element below its parent, you have to create a new stacking context to change the default stacking order. Positioning the pseudo-element (absolute or relative) and assigning a z-index value other than “auto” creates a new stacking context.

What does :: before and :: after do?

Definition and UsageThe ::before selector inserts something before the content of each selected element(s). Use the content property to specify the content to insert. Use the ::after selector to insert something after the content.

What is :: before in xpath?

::before is a pseudo element which allows you to insert content onto a page from CSS (without it needing to be in the HTML). While the end result is not actually in the DOM, it appears on the page as if it is.

What is :: before for?

::before (:before) In CSS, ::before creates a pseudo-element that is the first child of the selected element. It is often used to add cosmetic content to an element with the content property. It is inline by default.


1 Answers

Your div and its ::after pseudo-element are members of the same stacking context, in this case the root stacking context. The new stacking context you give the pseudo-element would be used as a reference to its children (which are non-existent), but the z-index value applies to the current stacking context. And the CSS spec dictates the following paint order for each stacking context:

Within each stacking context, the following layers are painted in back-to-front order:

  1. the background and borders of the element forming the stacking context.
  2. the child stacking contexts with negative stack levels (most negative first).
  3. the in-flow, non-inline-level, non-positioned descendants.
  4. the non-positioned floats.
  5. the in-flow, inline-level, non-positioned descendants, including inline tables and inline blocks.
  6. the child stacking contexts with stack level 0 and the positioned descendants with stack level 0.
  7. the child stacking contexts with positive stack levels (least positive first).

Look, child stacking contexts with negative stack levels, such as your div::after are painted before the positioned descendants with stack level 0, such as the div itself. This explains the behavior you noticed.

like image 186
bfavaretto Avatar answered Sep 21 '22 17:09

bfavaretto