CSS Selektoren - :nth-match() vs :nth-child(... of S)
Rolf B
- css
- selektor
Die Selektion von HTML-Elementen mit der CSS Pseudoklasse :nth-child()
wird schwierig, wenn die Elemente noch zusätzlich über Klassen- oder Attributselektoren eingegrenzt werden sollen und die Kindelement-Zählung nur innerhalb der zusätzlichen Selektoren stattfinden soll.
Um das zu lösen, wurde bereits 2011, im ersten Entwurf der CSS Selectors Level 4 Spezifikation, die Pseudoklasse :nth-match() vorgeschlagen.
Lesen Sie hier, was daraus wurde.
Angenommen, Sie hätten eine Tabelle und möchten die Lesbarkeit dadurch verbessern, dass Sie nach jeder dritten Zeile eine horizontale Linie einfügen. Das gelingt beispielsweise mit
#mytable tbody tr:nth-of-type(3n) {
border-bottom: thin solid black;
}
Solange alle Rows der Tabelle dargestellt werden, wird auf diese Weise unter jeder dritten Zeile ein Strich gezogen. Aber was ist, wenn diese Tabelle noch eine Filterfunktion hätte, und die sichtbaren Zeilen mit einer Klasse match
versehen werden. Die CSS-Regel für eine solche Filterung könnte so aussehen:
#mytable.filtered tbody tr:not(.match) {
visibility:collapse;
}
Möchte man die Hilfslinien ergänzen, könnte man das so versuchen:
#mytable tbody tr.match:nth-of-type(3n) {
border-bottom: thin solid black;
}
Aber das funktioniert nicht, weil der Selektor tr.match:nth-of-type(3n)
aus drei Teilen besteht (Elementselektor, Klassenselektor, Pseudoklassenselektor), die alle unabhängig voneinander bewertet werden und deren Ergebnis UND-verknüpft wird.
tr
tr
-Elemente.match
match
In einer Tabelle mit 5 Zeilen, in der die Zeilen 1 und 5 sichtbar sind, würde dieser Selektor auf keine Zeile zutreffen, weil in jeder Zeile entweder der Klassenselektor .match
oder der Pseudoklassenselektor :nth-of-type(3n)
unzutreffend ist.
Was gebraucht wird, ist ein zweistufiges Vorgehen. Zunächst müssen alle sichtbaren Rows ermittelt werden, und von diesen Rows diejenigen mit gerader Nummer. Bisher ging das nur mit Hilfe von JavaScript.
Tatsächlich gibt es schon seit 2011 einen Vorschlag für eine CSS-Lösung: die :nth-match
Pseudoklasse. tr.match:nth-match(3n)
würde das Gewünschte leisten. Diese Pseudoklasse wurde allerdings 2013 wieder verworfen, zu Gunsten einer erweiterten Syntax von :nth-child()
:
:nth-child(An+B of S)
Safari unterstützt das seit 2015. Der Rest der Browserwelt hat sich acht Jährchen Bedenkzeit gegönnt, aber seit März 2023 steht dieser Selektor in Chromium-Browsern (Version 111) zur Verfügung, im April erschien Opera 98 mit diesem Feature und Firefox ist im Mai mit Version 113 nachgezogen (siehe Kompatibilität bei caniuse.com).
S
zu verstehen?Dabei handelt es sich um einen CSS Selektor, der die Elemente bestimmt, die für :nth-child berücksichtigt werden sollen. Die Spezifikation ist hier noch etwas im Fluss. Der neueste Entwurf besagt, dass es sich dabei um eine „complex-real-selector-list“ handele, was bedeutet: ein CSS Selektor, in dem außer Pseudoelementen alles verwendet werden kann, selbst Kommata. Der offizielle Working Draft formuliert allgemeiner und spricht von einer "complex-selector-list parsed as a forgiving selector", d.h. die Einschränkung der Pseudoelemente ist nicht vorhanden. Dafür wird aber gefordert, dass für den Fall, dass eine Selektorliste einen ungültigen Selektor enthält, die übrigen Selektoren der Liste trotzdem berücksichtigt werden sollen.
Für unser Beispiel mit der gefilterten Zebrastreifentabelle würden wir also schreiben können:
#mytable.filtered tbody tr:nth-child(3n of .match) {
background-color: #e0e0e0;
}
wodurch dann nur die Elemente für die nth-child-Zählung berücksichtig werden, die die Klasse .match tragen.
Die gleiche Erweiterung existiert für :nth-last-child().
Was es nicht gibt, ist die of-Erweiterung für :nth-of-type. Das hat einen guten Grund: die :nth-of-type()
-Pseudoklasse ist ein Sonderfall von :nth-child(… of S)
:
#mytable tbody tr:nth-of-type(3n of .match) { ... }
Ziehen Sie den Elementselektor für tr
einfach in die Klammer hinein, wodurch :nth-child ganz automatisch die Selektion des Elementtyps mit übernimmt.
#mytable tbody :nth-child(3n of tr.match) { ... }
THX. Hat mir weitergeholfen, um die Hilfslinien zu ergänzen.