Eine kleine Erinnerung daran, dass Pseudo-Elemente irgendwie Kinder sind.

Avatar of Chris Coyier
Chris Coyier am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

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

Six items in a clean two-by-two grid

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

Six items in a two-by-two grid, but with a seventh item at the beginning, pushing elements over by one

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

DevTools with a ::before element selected

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?