Z-index при использовании:: after под элементом

Если мы используем z-index в сочетании с position: absolute;, его можно поместить ::before элемента под собой. Есть хороший пример в другом вопросе (jsfiddle.net/Ldtfpvxy).

В основном

<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 */
}

оказывает:

enter image description here

Таким образом, контекст/порядок стекирования определяется z-index. Но когда я применяю z-index: 1; к элементу и z-index: -1; к его ::before, я не могу добиться того же.

Только если я опускаю z-index из элемента.

Любые идеи, почему это так? Является ли элемент визуализированным после его псевдонимов ::before и ::after, поэтому они получают одинаковый z-index?

Работа: https://jsfiddle.net/Ldtfpvxy/
Не работает: https://jsfiddle.net/Ldtfpvxy/1/ (добавлен только элемент z-index: 1; в элемент)

Ответы

Ответ 1

Ваш div и его псевдоэлемент :: after являются членами одного и того же контекста стека, в данном случае корневого контекста стека. Новый контекст стека, который вы задаете псевдоэлементу, будет использоваться как ссылка на его дочерние элементы (которых не существует), но значение z-index применяется к текущему контексту стека. И спецификация CSS определяет следующий порядок рисования для каждого контекста стека:

Внутри каждого контекста стекирования следующие слои закрашиваются в обратном порядке:

  1. фон и границы элемента, формирующего контекст стека.
  2. дочерние стековые контексты с отрицательными уровнями стека (сначала наиболее негативные).
  3. входящие, не встроенные, не позиционированные потомки.
  4. не позиционированные поплавки.
  5. встроенные непозиционированные потомки на уровне строк, включая встроенные таблицы и встроенные блоки.
  6. дочерние контексты стека с уровнем стека 0 и позиционированные потомки с уровнем стека 0.
  7. дочерние стековые контексты с положительными уровнями стека (сначала наименее положительные).

Посмотрите, дочерние контексты стека с отрицательными уровнями стека, такие как ваш div::after, рисуются перед позиционированными потомками с уровнем стека 0, такими как сам div. Это объясняет поведение, которое вы заметили.

Ответ 2

Указывая z-index вы создаете новый стековый контент;

если это делается только для псевдоэлемента child ::after родитель не установит новый стековый контент, и все будет работать так, как ожидается.

Но добавление z-index к родительскому элементу запустит новый стек (который также обернет дочерний стек..).
И если вы посмотрите на первые 2 пункта спецификации рендеринга стека, вы увидите, что фон будет отрисован раньше других дочерних стеков:

Внутри каждого контекста стекирования следующие слои закрашиваются в обратном порядке:

  1. фон и границы элемента, формирующего контекст стека.
  2. дочерние стековые контексты с отрицательными уровнями стека (сначала наиболее негативные).
  3. ......

Вот пример, чтобы прояснить различное поведение рендеринга для вложенного фона стека.


position: relative не является обязательным; с положением по умолчанию position:static, z-index имеет никакого эффекта.