css примеры - Можно ли установить порядок укладки псевдоэлементов ниже их родительского элемента?




псевдоэлементы анимация (7)

Я пытаюсь создать элемент с помощью :after псевдоэлемента CSS-селектора

#element {
    position: relative;
    z-index: 1;
}

#element::after {
    position:relative;
    z-index: 0;
    content: " ";
    position: absolute;
    width: 100px;
    height: 100px;
}

Кажется, что элемент ::after не может быть ниже самого элемента.

Есть ли способ, чтобы псевдоэлемент был ниже, чем сам элемент?


Answers

Pseudo-elements рассматриваются как потомки их ассоциированного элемента. Чтобы расположить псевдоэлемент ниже его родителя, вы должны создать новый контекст стекирования, чтобы изменить порядок укладки по умолчанию.
Позиционирование псевдоэлемента (абсолютное) и присвоение значения z-index, отличного от «auto», создает новый контекст стекирования.

#element { 
    position: relative;  /* optional */
    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 */
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Position a pseudo-element below its parent</title>
</head>
<body>
  <div id="element">
  </div>
</body>
</html>


Говоря о спецификации ( http://www.w3.org/TR/CSS2/zindex.html ), поскольку позиционируется a.someSelector, он создает новый контекст стекирования, который его дети не могут вырваться. Оставьте a.someSelector unpositioned, а затем дочерний a.someSelector: после этого можно разместить в том же контексте, что и a.someSelector.


Здесь есть две проблемы:

  1. В спецификации CSS 2.1 указано, что «элементы: before и: after псевдоэлементы взаимодействуют с другими ящиками, такими как окна запуска, как если бы они были реальными элементами, вставленными только внутри их связанного элемента». Учитывая, что z-индексы реализованы в большинстве браузеров, довольно сложно (читайте, я не знаю, каким образом), чтобы перемещать контент ниже, чем z-индекс их родительского элемента в DOM, который работает во всех браузерах.

  2. Номер 1 выше не обязательно означает, что это невозможно, но второе препятствие для него на самом деле хуже: в конечном счете это вопрос поддержки браузера. Firefox не поддерживал позиционирование сгенерированного контента вообще до FF3.6. Кто знает о браузерах, таких как IE. Поэтому, даже если вы можете найти хак, чтобы он работал в одном браузере, очень вероятно, что он будет работать только в этом браузере.

Единственное, что я могу думать о том, что это будет работать в браузерах, - это использовать javascript для вставки элемента, а не CSS. Я знаю, что это не отличное решение, но: и раньше, и после псевдоселекторов просто не выглядят так, как будто они режут его здесь.


Я знаю, что этот вопрос древний и имеет принятый ответ, но я нашел лучшее решение проблемы. Я размещаю его здесь, поэтому я не создаю дублирующий вопрос, и решение по-прежнему доступно для других.

Переключите порядок элементов. Используйте псевдонимы :before псевдоэлементом для содержимого, которое должно быть внизу, и отрегулируйте поля для компенсации. Очистка полей может быть грязной, но желаемый z-index будет сохранен.

Я успешно тестировал это с помощью IE8 и FF3.6.


Установите z-index :before или :after псевдоэлемента в -1 и присвойте ему position которая чтит свойство z-index ( absolute , relative или fixed ). Это работает потому, что z-index относится к его родительскому элементу, а не к <html> , который является значением по умолчанию для других элементов. Это имеет смысл, поскольку они являются дочерними элементами <html> .

Проблема, с которой я столкнулся (что привело меня к этому вопросу и принятому ответу выше), заключалось в том, что я пытался использовать :after псевдоэлемента, чтобы получить представление о фоне элемента с z-index 15 и даже когда задано с z-index 14, он все еще отображается поверх его родителя. Это связано с тем, что в этом контексте стекирования у родителя есть z-index 0.

Надеюсь, это поможет немного разъяснить, что происходит.


Попробуйте

el {
  transform-style: preserve-3d;
}
el:after {
  transform: translateZ(-1px);
}

:before и :after работает только для узлов, которые могут иметь дочерние узлы, поскольку они вставляют новый узел в качестве первого или последнего узла.





css z-index pseudo-element