Hier ist ein Container mit einigen Kindelementen
<div class="container">
<div>item</div>
<div>item</div>
<div>item</div>
</div>
Wenn ich mache
.container::before {
content: "x"
}
Mache ich im Wesentlichen
<div class="container">
[[[ ::before psuedo-element here ]]]
<div>item</div>
<div>item</div>
<div>item</div>
</div>
Was sich *meistens* wie ein Kind-Element verhalten wird. Eine knifflige Sache ist, dass kein Selektor es auswählt, außer dem, den du zu seiner Erstellung verwendet hast (oder einem ähnlichen Selektor, der buchstäblich ein ::before oder ::after ist, das an derselben Stelle landet).
Zur Veranschaulichung, nehmen wir an, ich richte diesen Container als 2x3-Grid ein und mache jedes Element zu einer Art Pillbox-Design
.container {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 0.5rem;
}
.container > * {
background: darkgray;
border-radius: 4px;
padding: 0.5rem;
}
Ohne das Pseudo-Element wäre das so

Wenn ich den Pseudo-Element-Selektor wie oben hinzufüge, würde ich das bekommen

Es macht Sinn, kann aber auch überraschend sein. Pseudo-Elemente sind oft dekorativ (sie sollten *fast nur* dekorativ sein), daher fühlt es sich seltsam an, wenn sie an einem Content-Grid teilnehmen.
Beachte, dass der Selektor .container > * ihn nicht erfasst und darkgray gemacht hat, weil man ein Pseudo-Element nicht so auswählen kann. Das ist eine weitere kleine Stolperfalle.
Im Alltag finde ich, dass Pseudo-Elemente typischerweise absolut positioniert sind, um etwas Dekoratives zu tun – also, wenn du hättest
.container::before {
content: "";
position: absolute;
/* Do something decorative */
}
…würdest du es wahrscheinlich nicht einmal bemerken. Technisch gesehen ist das Pseudo-Element immer noch ein Kind, es ist also immer noch da und tut seine Sache, nimmt aber nicht am Grid teil. Das ist auch nicht nur bei CSS Grid so. Wenn du zum Beispiel Flexbox verwendest, stellst du fest, dass dein Pseudo-Element zu einem Flex-Item wird. Du kannst dein Pseudo-Element auch frei fließen lassen oder mit ihm andere Layout-Arbeiten durchführen.
DevTools macht ziemlich deutlich, dass es wie ein Kind-Element im DOM ist

Es gibt noch ein paar weitere Stolperfallen!
Eine ist :nth-child(). Man sollte denken, dass, wenn Pseudo-Elemente tatsächlich Kinder sind, sie :nth-child()-Berechnungen beeinflussen, aber das tun sie nicht. Das bedeutet, dass etwas wie dieses
.container > :nth-child(2) {
background: red;
}
…denselben Element auswählen wird, unabhängig davon, ob ein ::before Pseudo-Element vorhanden ist oder nicht. Das Gleiche gilt für ::after und :nth-last-child und ähnliche. Deshalb habe ich "irgendwie" in den Titel aufgenommen. Wenn Pseudo-Elemente genau wie Kind-Elemente wären, würden sie diese Selektoren beeinflussen.
Eine weitere Stolperfalle ist, dass man ein Pseudo-Element in JavaScript nicht so auswählen kann wie ein reguläres Kind-Element. document.querySelector(".container::before"); wird null zurückgeben. Wenn der Grund, warum du versuchst, das Pseudo-Element in JavaScript zu bekommen, darin besteht, seine Stile zu sehen, kannst du das mit ein wenig CSSOM-Magie tun
const styles = window.getComputedStyle(
document.querySelector('.container'),
'::before'
);
console.log(styles.content); // "x"
console.log(styles.color); // rgb(255, 0, 0)
console.log(styles.getPropertyValue('color'); // rgb(255, 0, 0)
Sind dir schon mal Stolperfallen bei Pseudo-Elementen aufgefallen?
Was an diesem Verhalten relativ nützlich ist, ist, dass du deine Pseudo-Elemente leicht in der Mitte des übergeordneten Elements (oder generell positionieren) kannst, indem du dem übergeordneten Element
display: flex;hinzufügst. Zum Beispiel beim Hinzufügen von benutzerdefinierten Markierungen zu<li>-Elementen. Wenn das Listenelement ein Flexbox ist, werden sein::beforePseudo-Element und sein Textinhalt so ausgerichtet, wie sie sollten.Das ist auch etwas, das erwähnenswert ist: diese Pseudo-Elemente in Grid und Flexbox werden genau gleich behandelt wie Textknoten. Schließlich kannst du eine Struktur haben wie
Textknoten Ein weiterer Textknoten