Selektoren in CSS/strukturelle Pseudoklassen

Aus SELFHTML-Wiki
Selektoren in CSS(Weitergeleitet von An+B)
Wechseln zu: Navigation, Suche

Bei Pseudoklassen handelt es sich um einfache Selektoren, die ein Element dann ansprechen, wenn es eine bestimmte Eigenschaft besitzt. So lassen sich zum Beispiel Elemente auswählen, die das erste Kindelement eines anderen Elementes sind.

Strukturelle Pseudoklassen sind dafür gedacht, Elemente aufgrund ihrer Position im DOM zu selektieren.

Im Einzelnen sind dies

  • :root, für das Wurzelelement
  • :empty, für leere Elemente
Beachten Sie: Selektoren wie strukturelle Pseudoklassen werden nicht auf die tatsächliche Reihenfolge und Verschachtelung der Elemente in einem Dokument angewendet, sondern auf den vom Parser erzeugten Elementbaum (DOM). Dieser weicht z. B. dann vom Quelltext des Dokuments ab, wenn der HTML-Parser Fehlerkorrekturen durchführt.

root

Mithilfe des Selektors :root ist es möglich, die Wurzel eines Dokumentes anzusprechen. In HTML-Dokumenten ist dies immer <html>. Deshalb ist :root {foo: bar;} dasselbe wie html {foo: bar} allerdings mit höherer Spezifität.

Beispiel ansehen …
<!doctype html> <html> <head> <meta charset="utf-8"> <title>CSS-Beispiel: Pseudoklasse root</title> <style> :root { color: red; } html { color: blue; } body { width: 40em; } </style> </head> <body> <h1>Demonstration der Pseudoklasse <code>:root</code></h1> <p>Von Selektoren mit gleicher ...</p> </body> </html>

Von Selektoren mit gleicher Spezifität überschreibt normalerweise der letztaufgeführte Selektor die Einstellungen des vorhergehenden. Deshalb würde man eine blaue Schrift erwarten. In Browsern, die :root korrekt interpretieren, ist die Schrift des Dokumentes jedoch rot.

Selektoren für Kindelemente

Das DOM ist so organisiert, dass jedes Element eine Liste seiner Kind-Elemente besitzt. Jedes Kind-Element hat eine Positionsnummer in dieser Liste. Diese Positionnummern beginnen übrigens mit 1, nicht mit 0.

Manchmal möchte man, dass ein (einfacher) Selektor nur dann zutrifft, wenn das angesprochene Element eine bestimmte Positionsnummer in der Kindelement-Liste hat.

Und manchmal möchte man auch, dass nur ein Teil der Elemente in der Kindelement-Liste betrachtet wird und will die Positionsnummer innerhalb dieses Teiles zur Selektion verwenden. Der Unterschied zwischen diesen beiden Wünschen ist anschaulich etwa der zwischen erstem Kind und erster Tochter. Diese Form der Selektion kann auf zwei Wegen geschehen: entweder mit der of-Erweiterung der Pseudoklassen in diesem Abschnitt, oder mit den -of-type()-Pseudoklassen, die im nachfolgenden Abschnitt beschrieben werden.

first-child

Mithilfe des Selektors :first-child ist es möglich, nur das erste Kindelement auszuwählen.

Beispiel ansehen …
:first-child { 
  border: medium solid blue; 
}
li:first-child {
	background-color: skyblue;
}

In diesem Beispiel erhält die Überschrift erster Ordnung einen blauen Rahmen, weil sie das erste Kindelement des Elementes „body“ ist. Der Elementtyp wird hier nicht angegeben, wir hätten auch *:first-child schreiben können.

Ebenso erhält das erste Listenelement einen blauen Rahmen, weil es das erste Kindelement der ungeordneten Liste ist. Das Beispiel hat wenig Strukturen, deshalb gibt es keine weiteren blauen Rahmen, aber zumeist wird ein „Rundumschlag“ wie in diesem Beispiel zu viele Elemente treffen.

Der verbundene Selektor li:first-child nutzt den Typselektor li und die Pseudoklasse :first-child, um gezielt li-Elemente auszuwählen, die das erste Kind in ihrer Liste sind.

Beachten Sie: Wie bei allen verbundenen Selektoren gilt, dass die darin enthaltenen einfachen Selektoren alle zutreffen müssen. Beispiel: Eine Liste darf außer li-Elementen auch script- oder template-Elemente enthalten. Würde ein solches vor dem ersten li Element stehen, würde :first-child und damit li:first-child nicht zutreffen.
Beachten Sie: Aus dem gleichen Grund würde der Selektor h2:first-child kein Element selektieren, weil es im Dokument keine h2-Überschrift gibt, die das erste Kind ihres Elternelements ist. Dafür wäre dann first-of-type oder :nth-child(1 of h2) zu verwenden.

Kommentare oder Text gelten übrigens nicht als Elemente. Ein Kommentar vor dem ersten li-Element würde die :first-child Eigenschaft dieses Elements nicht aufheben.

last-child

Der Selektor :last-child kann verwendet werden, um das letzte Kind eines Elternelementes zu selektieren.

Beispiel ansehen …
:last-child { 
  border: medium solid purple; 
}
li:last-child {
    background-color: pink;
}
strong:last-child {
	border: none;
	color:purple;
}

In diesem Beispiel erhält der 3. Absatz einen lila Rahmen, weil er das letzte Kindelement des Elementes „body“ ist. Ebenso erhält das dritte Listenelement einen lila Rahmen, weil es das letzte Kindelement der ungeordneten Liste ist. Auch auf „body“ selbst als letztes Kind des html-Elements trifft der Selektor zu.

Mit li:last-child {...} kann gezielt das letzte Kind einer Liste selektiert werden.

Auch strong:last-child {...} findet ein letztes Kind, da der folgende Text Plain text ist.

only-child

Der Selektor :only-child spricht ein Element an, welches das einzige Kind seines Elternelementes ist.

Beispiel ansehen …
li:only-child {
  border: medium dotted blue; 
}

In diesem Beispiel erhält nur das 4. Listenelement einen blauen Rahmen, weil es das einzige Listenelement in seiner Liste ist.

Beachten Sie: :only-child kann als die Verbindung :first-child:last-child aufgefasst werden. Allerdings sind das dann zwei Pseudoklassen, nicht eine, und damit ergäbe sich eine höhere Spezifität.

nth-child

Die bisherigen Selektoren waren Sonderfälle. Kommen wir nun zum allgemeinen Fall.

Mithilfe des Selektors :nth-child() ist es möglich, Kindelemente an beliebiger Position auszuwählen. Ausgehend von dieser Startposition kann jedes A-te weitere Element selektiert werden. Um dies formulieren zu können, verwendet :nth-child eine Schreibweise, die an eine mathematische Formel angelehnt ist.

Syntax

:nth-child(An+B)
Dies ist die allgemeine Syntax und beschreibt ein Wiederholungsmuster. A und B stehen hier für ganze Zahlen. Das n und das + sind Syntaxelemente.
Stellen Sie sich dazu vor, dass der Browser für n nacheinander die Werte 0, 1, 2, ... einsetzt und so eine Liste der Positionen erzeugt, für die die :nth-child-Pseudoklasse zutreffen soll.
Beispiel: 3n+2 würde die Positionen 2, 5, 8, 11... erzeugen und damit auf die Elemente an diesen Positionen zutreffen.
Natürlich erstellt der Browser nicht vorab eine unendliche Liste, sondern errechnet anhand der Elementposition, ob es ein passendes n gibt und entscheidet so, ob die Pseodoklasse zutrifft.
Beachten Sie: A und B müssen Konstanten sein. calc() oder var() sind an dieser Stelle nicht verwendbar!
:nth-child(even)
:nth-child(odd)
Es kommt häufig vor, dass man jede zweite Zeile einer Liste hervorheben will (Beispiele dazu folgen gleich), deshalb gibt es die Kurzformen even für die geraden Positionen und odd für die ungeraden Positionen. Damit wird die gewünschte Absicht deutlicher ausgedrückt ,als wenn man :nth-child(2n) (für even ) oder :nth-child(2n+1) (für odd) würde. Tipparbeit spart es nicht.
:nth-child(B)
Der Wiederholungsteil von An+B ist kann weggelassen werden. Mit :nth-child(4) würde man beispielsweise das vierte Element selektieren.
:nth-child(n+3)
Der Wiederholungsfaktor kann weggelassen werden, wenn er 1 ist. Diese Form selektiert alle Elemente ab dem dritten.
:nth-child(-n+3)
Der Wiederholungsfaktor kann auch negativ sein! In diesem Fall ist er -1, und die 1 kann weggelassen werden.
In dieser Form werden alle Elemente bis zum dritten selektiert. Mit :nth-child(-3n+8) würde jedes dritte Element selektiert, beginnend mit dem achten, und von da an rückwärts jedes dritte.
:nth-child(5n-1)
B kann ebenfalls negativ sein, dafür wird aus dem + ein Minuszeichen. Die selektierten Positionsnummern wären hier -1, 4, 9, 14, ... - und weil Positionsnummern immer größer als 0 sind, würde für Position -1 nie etwas gefunden. Man könnte also genauso gut :nth-child(5n+4) schreiben, das drückt aber nicht so deutlich aus, dass man das letzte Element jeder Fünfergruppe selektieren möchte.
:nth-child(… of selector)
verwendet einen zusätzlichen Filterselektor und wird im nächsten Abschnitt beschrieben.

Es wäre zuweilen praktisch, in den CSS-Eigenschaften auf den Wert von n im Selektor Bezug nehmen zu können. Diese Möglichkeit sieht CSS allerdings nicht vor. Ein entsprechender Änderungswunsch existiert allerdings[1], führte aber am Ende zur Einführung von sibling-index(), womit man auf n zurückrechnen kann. Das hat allerdings den Preis, die Konstanten A und B als magische Zahlen mehrfach notieren zu müssen, und es ist jetzt nicht mehr egal, ob man 3n+2 oder 3n-1 schreibt!

li:nth-child(3n+2) {
   --n: calc((sibling-index() - 2) / 3);
}

Tabelle im Zebralook

Beispieltabelle
    <table>
      <tbody>
        <tr><th>Zeile</th><th>Inhalt</th></tr>
        <tr><td>7</td><td>Text</td></tr>
        <tr><td>6</td><td>Text</td></tr>
        <tr><td>5</td><td>Text</td></tr>
        <tr><td>4</td><td>Text</td></tr>
        <tr><td>3</td><td>Text</td></tr>
        <tr><td>2</td><td>Text</td></tr>
        <tr><td>1</td><td>Text</td></tr>
        <tr><td>0</td><td>Text</td></tr>
      </tbody>
   </table>
Darstellung der Tabelle mit Streifenmuster ansehen …
      table {width: 95%;}
      th {
        background-color: #666; 
        color: #fff;
      }
      tr {
        background-color: #fffbf0;
        color: #000;
      }
      tr:nth-child(odd) {
        background-color: #e4ebf2;
      }

In diesem Beispiel wird eine Tabelle dargestellt.

Zunächst werden unter Verwendung des tr Selektors alle Zeilen mit background:#fffbf0; eingefärbt. Eine zweite Regel mit dem Selektor tr:nth-child(odd) trifft auf alle Zeilen mit ungerader Zeilennummer zu und setzt für sie die Hintergrundfarbe #e4ebf2.

Vorteil: Die Einfärbung wird erst im CSS festgelegt. Wenn eine weitere Zeile im HTML eingefügt wird, sind keine weiteren Änderungen am CSS nötig.

Nachteil: Falls Sie die Tabellendarstellung filtern, d. h. einzele Zeilen per CSS ausblenden, wird dies nicht berücksichtigt und das Streifenmuster funktioniert nicht mehr. Greifen Sie hierfür auf die of S Erweiterung von :nth-child() zurück und berücksichtigen Sie darin die Filterung.

Feld mit Schachbrettmuster

Tabelle mit Schachbrettmuster ansehen …
<style>
  tr:nth-child(odd) td:nth-child(odd),
  tr:nth-child(even) td:nth-child(even) {
    background: black;
  }
</style>
<body>
  <table>
    <tbody>
	  <tr><th>8</th><td></td>...<td></td></tr>
	  
          ...

	  <tr><th>1</th><td></td><td>...<td></td></tr>
	  <tr><th></th><th>A</th>...<th>H</th></tr>
	</tbody>
  </table>
</body>

In diesem Beispiel wird ein Schachbrett dargestellt. Neben den 8x8 Feldern, die durch normale Tabellenzellen dargestellt werden, erhält es mit th-Elementen noch Bezeichnungen für Spalten (A-H) und Reihen (1-8).

Standardmäßig sind die Tabellenzellen weiß. Die gezeigte CSS Regel besteht aus einer Selektor-Liste, die in den ungeraden Zeilen die Zellen in den ungeraden Spalten auswählt und in den geraden Zeilen die Zellen in den geraden Spalten. Dadurch wechselt in jeder Zeile die Position der schwarzen Felder und es entsteht das typische Schachbrettmuster.

{{Beachten|Die th Elemente zählen bei der even/odd Berechnung mit. Deshalb ist Feld A8 weiß - es ist zwar auf dem Schachbrett das erste (ungerade) Feld der ersten (ungeraden) Reihe, aber in der HTML-Tabelle ist es die zweite Spalte. Wir färben nur die td Elemente, deshalb ist die th-Zelle davor nicht schwarz geworden.

Siehe auch das Beispiel für die Pseudoklasse nth-of-type().

nth-child of selector

Wie schon mehrfach angeteasert, ist es zuweilen nicht sachgerecht, bei der nth-child()-Zählung alle Geschwisterelemente mitzuzählen. Die ursprüngliche Möglichkeit, die berücksichtigten Elemente genauer anzugeben, sind die ...-of-type()-Klassen, diese Möglichkeit wurde aber mit Level 4 der CSS Selektorspezifikation deutlich verbessert.

Die Pseudoklasse :nth-child(An+B) besitzt eine erweiterte Form :nth-child(An+B of S), in der Sie außer der Formel zur Berechnung der ausgewählten Elemente noch einen Selektor S hinzufügen. Dieser Selektor dient als Filter für die Elemente, die für die :nth-child-Berechnung herangezogen werden sollen.

Es gibt keine Einschränkungen für die Komplexität des verwendeten Filterselektors. Er kann Kombinatoren enthalten, es kann sogar eine Selektorliste sein. Für die :nth-child-Positionsberechnung eines Elements werden zunächst alle Kindelemente seines Elternelements über den of-Selektor gefiltert und dann geprüft, ob die An+B Positionsangabe zutrifft.

Wenn Sie in einer Liste, in der einige Einträge mit einer Klasse markiert sind, nur die ersten drei markierten Einträge hervorheben wollen, dann ist das mit :nth-child(-n+3 of .marker) einfach erledigt. Ohne of müssten Sie auf JavaScript zurückgreifen. Das folgende Beispiel zeigt den Unterschied der falschen Schreibweise li.marker:nth-child(-n+3) (die Vordergrundfarbe) und :nth-child(…of…) (die Hintergrundfarbe):

Die ersten drei Einträge mit marker-Klasse ansehen …
ul li.marker:nth-child(-n+3) {
   color: red;
}

ul :nth-child(-n+3 of li.marker) {
   background-color: yellow;
}
<ul>
   <li>Eins</li>
   <li class="marker">Zwei</li>
   <li class="marker">Drei</li>
   <li>Vier</li>
   <li>Fünf</li>
   <li class="marker">Sechs</li>
   <li>Sieben</li>
</ul>

nth-last-child

Der Selektor :nth-last-child() funktioniert in völliger Analogie zu :nth-child(), nur dass die Zählung von hinten beginnt. Die of selector Erweiterung ist ebenfalls verfügbar.

Beispiel ansehen …
tr:nth-last-child(3n+1) {
  background-color: #e4ebf2 ;
  color: #000;
}

In diesem Beispiel wird eine Tabelle dargestellt.

Zunächst werden alle Zeilen mit background:#fffbf0; eingefärbt. Dann werden mit Hilfe des Ausdrucks tr:nth-last-child(3n+1) { background-color: #e4ebf2; } die Zeilen 3, 6 und 9 (also die 1., 4. und 7. Zeile von hinten) anders eingefärbt.

Pseudoklassen für Kindelemente eines bestimmten Elementtyps

Von diesen Pseudoklassen werden nur die Kindelemente eines bestimmten Elementtyps betrachtet. Im Gegensatz dazu werden mit :…-child alle Kindelemente herangezogen. Der Unterschied ist anschaulich etwa der zwischen erster Tochter und erstem Kind.

Empfehlung: Verwenden Sie die …-type Pseudoklassen zusammen mit einem Elementselektor. h2:first-of-type findet zum Beispiel das erste h2-Element. Sie könnten den Elementselektor aber auch weglassen, erhalten dann aber ein Ergebnis, das nur selten einen Sinn ergibt, weil dann jedes Element, dass das letzte Kindelement seines Typs ist, ausgewählt wird.

first-of-type

Mithilfe des Selektors :first-of-type ist es möglich, die jeweils ersten Kindelemente eines bestimmten Typs auszuwählen.

Beispiel ansehen …
h2:first-of-type { 
  border: medium solid hotpink; 
}

In diesem Beispiel erhält die erste Überschrift zweiter Ordnung einen pinken Rahmen. Falls Ihr Dokument in – beispielsweise – mehrere <section>-Elemente aufgeteilt ist, in denen sich jeweils <h2>-Überschriften befinden, dann würde in jeder Section die erste h2 Überschrift diesen Rahmen erhalten.

Beachten Sie: Der Selektor h2:first-child würde hier nichts selektieren, weil die Überschriften zweiter Ordnung das zweite und vierte Kind des body-Elements sind.

last-of-type

Der Selektor :last-of-type funktioniert in völliger Analogie zu first-of-type.

die letzte Überschrift! ansehen …
h2:last-of-type { 
  border: medium solid firebrick; 
}

In diesem Beispiel erhält die letzte Überschrift zweiter Ordnung einen roten Rahmen.

Beachten Sie: Der Selektor h2:last-child könnte in diesem Beispiel nichts selektieren, weil die Überschriften zweiter Ordnung das zweit- und viertletzte Kind des body-Elements sind.

nth-of-type

Mithilfe des Selektors :nth-of-type() ist es möglich, das n-te Kindelement eines Elementtyps in einem Elternelementes zu selektieren. Der Selektor erwartet als Argument einen mathematischen Ausdruck, der einer arithmetischen Zahlenfolge mit ganzzahligen Koeffizienten entspricht, oder eins der Schlüsselwörter even oder odd für alle geraden oder ungeraden Elemente eines Typs.

Schachbrettmusster ansehen …
tr:nth-of-type(odd) td:nth-of-type(even){ 
  background: black; 
}
tr:nth-of-type(even) td:nth-of-type(odd) { 
  background: black; 
}

In diesem Beispiel wird ein Schachbrett dargestellt.

Zunächst werden in der 1., 3., 5. und 7. Tabellenzeile die geradzahligen td-Elemente mit einem schwarzen Hintergrund versehen. Das Feld B8 zum Beispiel ist schwarz, weil es das zweite „<td>-Kind“ der Zeile ist.

Anschließend werden in den geraden Tabellenzeilen die ungeraden td-Elemente schwarz eingefärbt. A7 ist schwarz, denn es ist das erste „<td>-Kind“ der Zeile.

Vergleiche: :nth-child

Beachten Sie: :nth-of-type(… of selector) existiert nicht. Verwenden Sie dafür :nth-child() mit einem of-Selektor, der den gewünschten Elementtyp enthält.

:nth-of-type(An+B) selektiert all diejenigen Geschwisterelemente deren „Platznummer“ bei Division durch A den Rest B lässt.

:nth-of-type(odd) ist identisch zu :nth-of-type(2n+1) oder :nth-of-type(2n-1) (ungerade Platznummer).

:nth-of-type(even) ist identisch zu :nth-of-type(2n) (gerade Platznummer).

:nth-of-type(B) selektiert nur das B-te Element des entsprechenden Typs.

:nth-of-type(n) selektiert alle Elemente des entsprechenden Typs.

nth-last-of-type

Der Selektor :nth-last-of-type funktioniert analog zu :nth-of-type(), nur dass die Zählung von hinten beginnt.

Beispiel ansehen …
p:nth-last-of-type(3n+1) {
  background-color: red; 
}

In diesem Beispiel erhalten der letzte, der 4.-letzte und der 7.-letzte Absatz einen roten Hintergrund, und zwar unabhängig davon, ob überhaupt, welche und wieviele Elemente davor, danach oder dazwischen stehen.

only-of-type

Der Selektor :only-of-type spricht ein Element dann an, wenn es das einzige Kind dieses Typs seines Elternelementes ist.

Beispiel ansehen …

em {

 font-weight: bold;

} em:only-of-type {

 color: red; 
}

In diesem Beispiel werden alle em-Elemente fett formatiert; das 3. erhält zusätzlich die Schriftfarbe rot, weil es das einzige em-Element seines Absatzes ist. Dass es noch ein b-Element als Geschwisterelement besitzt, ist nicht von Bedeutung, verhindert jedoch das Ansprechen durch em:only-child.

Beachten Sie: :only-of-type ist identisch zu :first-of-type:last-of-type, :first-of-type:nth-last-of-type(1), :nth-of-type(1):last-of-type sowie :nth-of-type(1):nth-last-of-type(1) allerdings mit anderer Spezifität.



Weblinks

  • w3c/csswg-drafts bei Github: Issue 8981: Expose n as a <calc-constant>