Nachfolger – Nachbar-Selektoren
Jetzt wird's kleinlich in der Nachbarschaft:
- Ein Nachfahren-Selektor oder Descendant Selector filtert Elemente unterhalb bestimmter Elemente.
- Ein Nachbar-Selektor oder Adjacent Selector filtert Elemente, die aufeinander folgen und auf derselben Ebene liegen.
Kontext ───┐ ┌── Selektiertes Element
│ │
▼ ▼
div p { … }
▲ │
└──┘
┌── Kontext ──┐ ┌── Selektiertes Element
│ │ │
▼ ▼ ▼
main ul.hangout:last-child { … }
▲ │
└────────────────────┘
Wir schreiben CSS-Regeln von links nach rechts, aber die Browser interpretieren CSS-Regeln von rechts nach links.
- E F
Nachfahren-Selektor | Descendant a img { border: 4 px solid orange }
Alle img-Tags, die innerhalb eines a-Tags liegen, auch in zweiter oder dritter Ebene. Zwischen dem Eltern-Selektor und dem Kind-Selektor sitzt ein Leerzeichen.- E > F
Kind-Selektor | Child div>table { border: thin dashed green; }
Alle table-Elemente, die direkt innerhalb eines div-Elements liegen. Selektoren, die durch ein >-, +- oder ~-Symbole voneinander getrennt sind, werden auch als »Kombination« bezeichnet.- E + F
Direkter Nachbar-Selektor | Adjacent h5 + p { font-weight: bold }
Das p-Element, das direkt auf eine Überschrift h5 folgt.- E ~ F
Indirekter oder allgemeiner Nachbar-Selektor h5 ~ p { color: dimgray }
Alle p-Elemente, die der Überschrift h5 folgen und auf derselben Ebene innerhalb eines Eltern-Elements liegen ().
Kontext-Selektoren wirken nicht nur auf CSS, sondern filtern mit querySelector und querySelectorAll Elemente mit Javascript.
Nachfahren-Selektor (Descendant)
<div> <h2> … </h2> <p> … </p> <ul> <li> … </li> <li><p> … </p></li> <li></li> </ul> <p> … </p> </div>
div p { color: white; background-color: red; }
Die Regel spricht alle p-Elemente an, die innerhalb von div-Elementen liegen.
Die Umkehrung wäre der has()-Selektor, der ein Eltern-Element nur dann anspricht, wenn es bestimmte Kind-Elemente enthalten würde, z.B. ein figure-Element nur, wenn ein figcation-Element unterhalb von figure liegt: figure:has(figcaption).
Kind-Selektor (Child)
div > p { color: white; background-color: red; }
trifft nur auf p-Elemente zu, die direkt unterhalb des div-Elements liegen.
Der Kind-Selektor birgt allerdings eine Falle: Bei Eigenschaften, die nicht vererbt werden, funktioniert der Kind-Selektor wie erwartet, aber bei erblichen (inherit) Eigenschaften wirken sich Eigenschaften auf alle Abkömmlinge aus.
- Ein direktes Kind von ul
- Ein direktes Kind von ul
- Kein direktes Kind vom obersten ul
- Ein direktes Kind von ul
- Kein direktes Kind vom obersten ul
- Ein direktes Kind von ul
ul.demolist > li { text-transform: uppercase; font-size: 1.2em; opacity: 0.5; text-align: right; border-bottom: 2px solid red; margin-bottom: 1.5em; }
font-size und und text-transform sind erbliche Eigenschaft, darum wirken sie auf alle li-Elemente, nicht nur auf direkte Kind-Elemente.
border und margin sind nicht erblich und wirken nur auf direkte Kind-Elemente des oberen ul-Elements. Vererbung – Inheritance – mit Ecken und Kanten …
Kombination mit class
Auch diese Kontext-Selektoren können z.B. durch Klassen- oder id-Selektoren noch weiter eingeschränkt werden.
div#nurHier p.content { color: white; background-color: green; width: 500px; }
Nur Inhalte von p-Elementen mit dem Attribut class="content", die innerhalb des div-Elements mit dem id-Attribut id="nurHier" liegen, werden den aufgeführten Regeln unterworfen.
CSS Vorgänger: Parent- oder Eltern-Selektor
Was lange Zeit fehlte, war ein Eltern-Selektor oder Parent Selector – die Option, das Eltern-Element oder Vorgänger-Elemente eines Elements anzusprechen. Die Gefahr von unbeabsichtigten Überschreibungen ist bei einem rückwärts (vom Kind auf den Vorfahren) gerichteten Selektor groß, und sogar unendliche Schleifen könnten durch einen CSS Vorfahren- oder Parent-Selector entstehen.
Der :has()-Selektor füllt heute die Lücke: Er trifft auf alle Elemente zu, die mindestens ein bestimmtes Element enthalten. In diesem Beispiel würden figure-Elemente gewählt, die ein figcaption-Element enthalten:
figure:has(figcaption) { border: 2px solid green; }
CSS :has kann entscheiden, ob ein ul-Element ein Untermenu hat markieren:
ul.hasmenu li:has(ul)::before { content: "▶"; }
Wenn ein li-Element unterhalb von ul.hasmenu ein weiteres ul-Element enthält, dann setze ▶ als Zeichen, dass hier mehr zu holen ist.