Kind- und Geschwisterselektoren

Avatar of Chris Coyier
Chris Coyier am

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

Wissen Sie, was der Unterschied zwischen diesen Selektoren ist?

ul li { margin: 0 0 5px 0; }
ul > li { margin: 0 0 5px 0; }

Ich gebe zu, es hat länger gedauert, als es wahrscheinlich sollte (schon damals), als ich die Grundlagen von CSS lernte. In beiden Fällen werden Listenelemente ausgewählt, die Kinder von ungeordneten Listen sind. Aber es gibt einen Unterschied zwischen Kindern und Nachkommen.

Der erste Selektor oben ist ein Nachkommen-Selektor. Er wählt alle Listenelemente aus, die sich irgendwo unterhalb einer ungeordneten Liste in der Markup-Struktur befinden. Das Listenelement könnte drei Ebenen tief in andere verschachtelte Listen eingebettet sein, und dieser Selektor wird es trotzdem finden. Der zweite Selektor oben ist ein Kind-Kombinator-Selektor. Das bedeutet, er wählt nur Listenelemente aus, die direkte Kinder einer ungeordneten Liste sind. Mit anderen Worten, er schaut nur eine Ebene tief in die Markup-Struktur, nicht tiefer. Wenn also eine weitere ungeordnete Liste tiefer verschachtelt wäre, würden die Listenelemente, die deren Kinder sind, von diesem Selektor nicht angesprochen.

Ich denke, jeder versteht den grundlegenden Nachkommen-Selektor, aber lassen Sie uns einen schnellen Überblick über die anderen Selektoren dieses Typs geben: den Kind-Kombinator, den benachbarten Geschwister-Kombinator und den allgemeinen Geschwister-Kombinator.

Kind-Kombinator

Diesen haben wir bereits in der Einleitung dieses Artikels behandelt. Lassen Sie uns dasselbe Beispiel mit einer visuellen Darstellung vertiefen.

Ich denke, die verschachtelte Liste ist ein perfektes Beispiel dafür, warum dieser Selektor nützlich ist. Er kann als eine Möglichkeit betrachtet werden, zu verhindern, dass sich Stile weiter nach unten vererben, als man es möchte. Vielleicht möchten Sie die äußersten Listenelemente groß und header-ähnlich gestalten, aber die verschachtelten Listen kleiner und eher wie Fließtext. Mit einem Kind-Kombinator können Sie nur diese obersten Listenelemente auswählen und müssen sich keine Sorgen machen, dass die großen/header-ähnlichen Stile auf die verschachtelten Listen übergreifen und Sie gegen diese Stile ankämpfen müssen.

Benachbarter Geschwister-Kombinator

Ein Selektor mit einem benachbarten Geschwister-Kombinator ermöglicht es Ihnen, ein Element auszuwählen, das direkt nach einem anderen bestimmten Element kommt.

p + p { font-size: smaller; } /* Selects all paragraphs that follow another paragraph */
#title + ul { margin-top: 0; } /* Selects an unordered list that directly follows the element with ID title */

Diese Selektoren können Ihnen helfen, Stile kontextbezogen anzuwenden. Vielleicht haben Sie viele Artikel auf einer Website. Die meisten beginnen mit <p>-Elementen und das sieht gut aus. Aber einige beginnen mit einer <ul>, die oben und unten einen Abstand hat, damit sie innerhalb eines Artikels gut aussieht. Aber wenn sie einen Artikel beginnen, verursacht dies eine unangenehme Lücke. Der letztere Selektor würde diesen oberen Abstand auf Null setzen, wenn er auf einen Titel folgt.

Hoffentlich hilfreiche Grafik

Allgemeiner Geschwister-Kombinator

Der allgemeine Geschwister-Kombinator-Selektor ist dem benachbarten Geschwister-Kombinator-Selektor, den wir uns gerade angesehen haben, sehr ähnlich. Der Unterschied ist, dass das ausgewählte Element den ersten Elementen nicht unmittelbar folgen muss, sondern irgendwo danach erscheinen kann.

Wenn wir die gleiche Beispielstruktur wie oben verwenden, wird das letzte <p>-Element vonp ~ pebenso ausgewählt, da es von einem anderen <p>-Element vorausgeht, auch wenn nicht direkt.

Beachten Sie, dass bei sowohl den allgemeinen Geschwister- als auch den benachbarten Geschwister-Selektoren die Logik innerhalb desselben Elternelements stattfindet. Das ist es, was Geschwister bedeutet... sie teilen sich denselben Elternteil. In den obigen grafischen Beispielen ist das der Grund, warum das umgebende <div> vorhanden ist. Wenn nach diesem <div> ein weiteres <p>-Element stünde, würde es immer noch von beiden ausgewählt werdendiv ~ punddiv + pobwohl es ein Geschwister und ein benachbartes Geschwister dieses <div> wäre.

Browser-Unterstützung

Diese sind alle ab IE 8 und höher sowie in allen anderen modernen Browsern gut einsatzbereit. IE 7 hat auch Unterstützung, aber beachten Sie, dass HTML-Kommentare sie durcheinanderbringen und dazu führen können, dass sie nicht übereinstimmen, wenn sie sich zwischen Geschwistern befinden.

Wenn Sie mehr Unterstützung als diese benötigen, hilft Ihnen das ie7-js Projekt (jetzt bis ie9.js aktualisiert), mit einer einzigen einfachen JavaScript-Einbindung Unterstützung für all dies bis hin zu IE 5.5 zu erhalten.

Wunsch

Ich habe es schon oft gesagt, aber eine der großen fehlenden Selektor-Stile in CSS ist eine Art "enthält" (oder "hat" oder "qualifiziert" oder wie auch immer man es nennen will. Die Idee ist, z. B. "wähle alle Absätze aus, die Bilder enthalten".

Es könnte so aussehen

p < img { width: 150%; } /* Not real! */

Anscheinend haben die zuständigen Stellen es aus komplexen Gründen (ich glaube, es hat mit Geschwindigkeit zu tun) mehrfach abgelehnt. jQuery kann das

$("p:has(img)")

Und kann sogar angepasst werden, um die "<" Syntax zu verwenden.

jQuery.parse.push(/^\s*(<)(\s*)(.*)$/);
jQuery.expr["<"] = jQuery.expr[":"].has;

Die Spezifikation

Es schadet nicht, auch die Spezifikation für diese Dinge durchzulesen.