Est-il possible de définir l'ordre d'empilement des pseudo-éléments en dessous de leur élément parent?

J'essaie de styliser un élément avec le sélecteur CSS:after pseudo élément

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

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

Il semble que l'élément ::after ne puisse pas être inférieur à l'élément lui-même.

Est-il un moyen d'avoir le pseudo élément inférieur de l'élément lui-même?

217
demandé sur adardesign 2010-06-13 19:56:37

7 réponses

Les Pseudo-éléments sont traités comme des descendants de leur élément associé. Pour positionner un pseudo-élément sous son parent, vous devez créer un nouveau contexte d'empilement pour modifier l'ordre d'empilement par défaut.
Positionner le pseudo-élément (absolu) et attribuer une valeur d'index z autre que "auto" crée le nouveau contexte d'empilement.

#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>
276
répondu arley 2015-01-21 20:23:07

Je sais que c'est un vieux fil, mais je ressens le besoin de poster la bonne réponse. La réponse réelle à cette question Est que vous devez créer un nouveau contexte d'empilement sur le parent de l'élément avec le pseudo-élément (et vous devez lui donner un index z, pas seulement une position).

Comme ceci:

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

Cela n'a rien à voir avec l'utilisation de pseudo-éléments :before OU :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>
211
répondu Adam 2017-08-14 13:05:37

Il y a deux problèmes en jeu ici:

  1. La spécification CSS 2.1 indique que " les éléments pseudo-éléments: avant et: après interagissent avec d'autres boîtes, telles que les boîtes de rodage, Comme s'ils étaient de vrais éléments insérés juste à l'intérieur de leur élément associé."Compte tenu de la façon dont les index z sont implémentés dans la plupart des navigateurs, il est assez difficile (Lire, Je ne connais pas de moyen) de déplacer le contenu inférieur à l'index z de leur élément parent dans le DOM qui fonctionne dans tous navigateur.

  2. Numéro 1 ci-dessus ne signifie pas nécessairement qu'il est impossible, mais le deuxième obstacle est en fait pire: en fin de compte, il est une question de support du navigateur. Firefox n'a pas pris en charge le positionnement du contenu généré jusqu'à FF3.6. Qui connaît les navigateurs comme IE. Donc, même si vous pouvez trouver un hack pour le faire fonctionner dans un navigateur, il est très probable qu'il ne fonctionne que dans le navigateur.

La seule chose à laquelle je peux penser qui va fonctionner à travers les navigateurs est d'utiliser javascript pour insérer l'élément plutôt que CSS. Je sais que ce n'est pas une excellente solution, mais les pseudo-sélecteurs :before et :after ne semblent pas vraiment le couper ici.

15
répondu Gabriel Hurley 2010-06-14 19:53:41

Parlant en ce qui concerne la spécification ( http://www.w3.org/TR/CSS2/zindex.html), puisqu'un. someSelector est positionné, il crée un nouveau contexte d'empilement dont ses enfants ne peuvent pas sortir. Laissez un. someSelector Non positionné, puis child un. someSelector: after peut être positionné dans le même contexte qu'un. someSelector.

11
répondu cweider 2010-06-14 20:20:12

Je sais que cette question Est ancienne et a une réponse acceptée, mais j'ai trouvé une meilleure solution au problème. Je le poste ici donc je ne crée pas de question en double, et la solution est toujours disponible pour les autres.

Changer l'ordre des éléments. Utilisez le pseudo-élément :before pour le contenu qui devrait être en dessous, et ajustez les marges pour compenser. Le nettoyage de la marge peut être désordonné, mais le z-index souhaité sera conservé.

J'ai testé cela avec IE8 et FF3. 6 réussi.

9
répondu D.N. 2011-02-28 20:09:00

Essayez-le

el {
  transform-style: preserve-3d;
}
el:after {
  transform: translateZ(-1px);
}
3
répondu Eugen Govorun 2018-07-19 21:49:35

Définissez le z-index du pseudo-élément :before ou :after sur -1 et donnez-lui un position qui honore la propriété z-index(absolute, relative, ou fixed). Cela fonctionne parce que le pseudo élément z-index est relatif à son élément parent, plutôt que <html>, qui est la valeur par défaut pour les autres éléments. Ce qui est logique parce qu'ils sont des éléments enfants de <html>.

Le problème que j'avais (qui m'a conduit à cette question et à la réponse acceptée ci-dessus) était que j'essayais d'utiliser un pseudo-élément :after pour obtenir une fantaisie avec un arrière-plan à un élément avec z-index de 15, et même lorsqu'il est défini avec un z-index de 14, Il était toujours rendu au-dessus de son parent. C'est parce que, dans ce contexte d'empilement, son parent a un z-index de 0.

J'espère que cela aide à clarifier un peu ce qui se passe.

2
répondu Noah Erickson 2017-11-17 03:08:11