mitmario.dev

Die Navigation ohne Extra-Klassen

CSS Im Browser 2 Min Lesezeit 3 BeispieleLektion 7 von 8

Eine Navigation mit Klassen wie aktiv und hat-untermenue muss jemand pflegen, und sobald eine fehlt, sieht ein Menüpunkt falsch aus. Die Kopfzeilen-Navigation des Portfolios kommt ohne aus, am Markup änderst du nichts. Alles, woran sich ein Selektor halten kann, steht schon da.

Drei Selektoren sind dafür gemacht.

:is()

is fasst zusammen
/* Statt article h2, article h3, aside h2, aside h3:
   zwei Klammern, vier Fälle. */
:is(article, aside) :is(h2, h3) {
  font-family: Georgia, serif;
  color: #1e3a8a;
}

:is() ist eine Abkürzung. :is(h1, h2, h3) bedeutet dasselbe wie h1, h2, h3. Was das bringt, merkst du erst bei längeren Selektoren. Statt article h2, article h3, aside h2, aside h3 steht dann :is(article, aside) :is(h2, h3), und aus vier Selektoren werden zwei Klammern.

Daneben gibt es :where(), das genauso aussieht und sich in einem Punkt anders verhält. Dieser Punkt hängt an der Spezifität, und die kommt in Lektion 3.2.

:has() entscheidet zum ersten Mal über das Elternteil

has schaut nach unten
/* Der Listenpunkt, der eine weitere Liste enthält */
.menue li:has(> ul) > a {
  font-weight: 700;
}

.menue li:has(> ul) > a::after {
  content: " ▾";
  color: #71717a;
}

Alle Selektoren bisher haben das Element ausgewählt, das am Ende der Kette steht, also Kind, Nachfahre oder folgendes Geschwister. :has() schaut zwar auch nach unten, entscheidet damit aber über das Element darüber. Es trifft ein Element aufgrund dessen, was darin steht.

li:has(> ul) trifft den Listenpunkt, der eine weitere Liste enthält. Bis Ende 2023 ging das nicht in jedem Browser. Solche Punkte bekamen deshalb eine Extra-Klasse, und die musste jemand pflegen. Seit Dezember 2023 können es alle großen Browser.

In die Klammer kommt ein Selektor, der vom Element aus gedacht ist. :has(> ul) heißt „ein direktes Kind vom Typ ul“, :has(ul) heißt „irgendwo darunter eine ul“, :has(+ p) heißt „danach folgt ein Absatz“. Das letzte ist der Fall aus den Kombinatoren, für den es keinen eigenen gibt. h2:has(+ p) trifft die Überschrift, auf die ein Absatz folgt, also das vorherige Geschwister.

Zwei praktische Fälle sind eine Karte, die anders aussieht, sobald sie ein Bild enthält (.karte:has(img)), und ein Formularfeld mit Rückmeldung an seinem Elternteil (.feld:has(input:invalid)).

Der aktive Punkt steht schon im Markup

Der aktive Punkt aus dem Markup
nav a {
  color: #52525b;
  text-decoration: none;
}

/* aria-current steht ohnehin im Markup, für Screenreader.
   Die Gestaltung hängt einfach daran. */
nav a[aria-current="page"] {
  color: #2563eb;
  font-weight: 700;
}

Für „welcher Menüpunkt ist gerade offen“ brauchst du keine Klasse, denn dafür gibt es schon ein Attribut. aria-current="page" sagt Screenreadern, welcher Link auf die gerade angezeigte Seite verweist. Das gehört ohnehin ins Markup, egal wie die Seite aussieht.

Die Regel hängt einfach daran, und dann kann nichts mehr auseinanderlaufen. Eine class="aktiv" neben einem aria-current sind zwei Wahrheiten über dieselbe Sache, und irgendwann widersprechen sie sich.

Fast der ganze Abschnitt auf einmal

Schwierig ist nicht die einzelne Eigenschaft, sondern das Zusammenspiel, und bei den Selektoren merkst du das zum ersten Mal. Die Navigation braucht Kombinatoren, um vom nav zu den Links zu kommen, einen Attribut-Selektor für aria-current, Zustände für Zeiger und Tastatur, eine Struktur-Pseudoklasse für den letzten Punkt in der Reihe und :has() für den Punkt mit Untermenü. Aus diesen Teilen baust du sie in der Aufgabe.

Zum Mitnehmen

Eine Navigation braucht keine eigenen Klassen: den aktiven Punkt nennt aria-current, den Punkt mit Untermenü findet :has(> ul), den letzten :last-child.

Jetzt du

Basis Konto, kostenlos

Zu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.

Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.

Was in dieser Lektion steckt

  • Artikel mit 3 Beispielen zum Ausprobieren

    Steht hier, ohne Konto lesbar.

  • Aufgabe im Editor, direkt im Browser geprüft

    Öffnet sich mit dem Basis Konto.