Можно ли установить порядок размещения псевдоэлементов ниже их родительского элемента? - PullRequest
246 голосов
/ 13 июня 2010

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

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

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

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

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

Ответы [ 9 ]

312 голосов
/ 30 мая 2012

Псевдоэлементы рассматриваются как потомки связанных с ними элементов. Чтобы расположить псевдоэлемент под его родительским элементом, необходимо создать новый контекст стека , чтобы изменить порядок стеков по умолчанию. Позиционирование псевдоэлемента (абсолютное) и присвоение значения 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>
231 голосов
/ 31 января 2012

Я знаю, что это старая ветка, но я чувствую необходимость опубликовать правильный ответ.Реальный ответ на этот вопрос заключается в том, что вам нужно создать новый контекст стека для родительского элемента с псевдоэлементом (и вам фактически нужно дать ему z-index, а не просто позицию).

Как это:

#parent {
    position: relative;
    z-index: 1;
}
#pseudo-parent {
    position: absolute;
    /* no z-index allowed */
}
#pseudo-parent:after {
    position: absolute;
    top:0;
    z-index: -1;
}

Это не имеет ничего общего с использованием: before или: after псевдоэлементов.

#parent { position: relative; z-index: 1; }
#pseudo-parent { position: absolute; } /* no z-index required */
#pseudo-parent:after { position: absolute; z-index: -1; }

/* Example styling to illustrate */
#pseudo-parent { background: #d1d1d1; }
#pseudo-parent:after { margin-left: -3px; content: "M" }
<div id="parent">
 <div id="pseudo-parent">
   &nbsp;
 </div>
</div>
36 голосов
/ 20 июля 2018

Попробуйте

el {
  transform-style: preserve-3d;
}
el:after {
  transform: translateZ(-1px);
}
15 голосов
/ 14 июня 2010

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

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

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

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

11 голосов
/ 15 июня 2010

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

9 голосов
/ 28 февраля 2011

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

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

Я успешно проверил это с IE8 и FF3.6.

4 голосов
/ 17 ноября 2017

Установите 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.

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

0 голосов
/ 03 апреля 2019

Я исправил это очень просто:

.parent {
  position: relative;
  z-index: 1;
}

.child {
  position: absolute;
  z-index: -1;
}

То, что это делает, это складывает родительский элемент в z-index: 1, что дает дочернему пространству «конец» в z-index: 0, так как другие элементы dom «существуют» в z-index: 0. Если мы не не предоставьте родителю z-индекс 1, дочерний элемент окажется ниже других элементов dom и, следовательно, не будет виден.

Это также работает для псевдоэлементов, таких как : после

0 голосов
/ 21 марта 2019

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

То, что вам нужно, это:

parent{
  z-index: 1;
}
child{
 position:relative;
 backgr
...