7.11.09
Ente Ente Ente – Folgen in CSS
CSS3 bringt eine ganze Palette neuer Selektierungsmöglichkeiten mit. Beinahe uneingeschränkt kann man sich damit durch den DOM-Wald hangeln und fast jedes noch so unbestimmte Element auswählen. Einen großen Beitrag zu dieser Erleichterung tragen die neuen Structural pseudo-classes bei. Während man bei der Verwendung von first-child und last-child noch keine größeren Probleme haben dürfte, gestaltet sich der Gebrauch von nth-child() und nth-of-type() etc. schwieriger, was schon beim Namen beginnt.
Der Name: Was ist „nth“?
Im Mathematikunterricht hat jeder schon einmal etwas von dem „n-ten Element“ gehört und sich dabei gefragt, was Enten auf einmal mit Mathe zu tun haben.
Spätestens nach dem zweiten „WTF?“, das durch den Klassenraum schallte, erklärte der Lehrende, dass es sich dabei um eine allgemeine Form für „Das erste, zweite, dritte, … Element“ handelt.
Dieses allgemeine „n-te“ findet sich im Englischen als „nth“ wieder (4th, 5th, 6th, … nth). Der Selektor nth-child() wählt jedes Element aus, auf das die nachfolgenden Bedingung passt. Diese Bedingung steht in Klammern.
Die Bedingung in den Klammern
Und wieder mache ich zuerst einen Ausflug in die Mathematik. In den Klammern steht nämlich eine explizite Folgenvorschrift der Form „an+b“. Das n ist hier die praktische Variable, a und b werden durch ganzzahlige Werte ersetzt.
Ein Beispiel für die Funktionsweise:
<!-- HTML: Eine Liste -->
<ul id="vater">
<li>Brigitte</li>
<li>Joachim</li>
<li>Maybritt</li>
<li>Ilse</li>
<li>Klaus</li>
<li>Orlof</li>
<li>Bruno</li>
</ul>
Und das CSS:
/* CSS */
#vater :nth-child(2n+0) {
background: red;
}
Hier haben wir es mit einem Vater zu tun, der sieben Kinder hat. Die Pseudo-Klasse nth-child(2n+0) wählt nun all’ diejenigen Elemente aus, die der Folgenvorschrift 2n+0 entsprechen und einen gemeinsamen übergeordneten Verwandten haben.
Zur Veranschaulichung hier ein Auszug einer Wertetabelle:
| 1 | 2 | 3 | 4 | 5 | n |
|---|---|---|---|---|---|
| 2 | 4 | 6 | 8 | 10 | 2n+0 |
Es werden also Joachim (2. Kindelement), Ilse (4. Kindelement) und Orlof (6. Kindelement) ausgewählt und mit einem roten Hintergrund versehen. Oder eben allgemein: Es wird jedes „2n+0“-te Element ausgewählt, für alle n∈ℕ (n ist Element der Natürlichen Zahlenmenge).
Den Ausdruck „2n+0“ könnte man auch als „2n-0“ schreiben. Da die Null aber ohnehin keine Auswirkung hat, kann man diese auch ganz weglassen. Die Vorschrift „2n“ hat aber auch einen reservierten Alias: even. So kann man mittels :nth-child(even) die gleiche Selektierung erreichen. Das Gegenstück dazu wäre „odd“, welches alle Kindelemente mit ungeradem Index auswählen würde und 2n+1 entspräche.
Anstatt die Pseudo-Klasse :first-child zu benutzen, kann man das gleiche mittels nth-child und dem Ausdruck :nth-child(1) erreichen, denn das Angeben einer variablen Komponente n ist optional, was daher rührt, dass :nth-child(0n+1) den gleichen Effekt hätte, aber weniger übersichtlich aussähe.
Man kann mit dem Selektor auch mehrere Elemente auswählen. Der Ausdruck :nth-child(-n+4) wählt z.B. die ersten vier Elemente aus, der Ausdruck *, denn als positive Indexes lassen sich hier nur 4, 3, 2 und 1 errechnen. Negative Indexes bzw. den nullten Index gibt es nicht.:nth-child(n-4) alle außer den ersten Vieren
*Anmerkung: Denkfehler des Autors, danke an Tim!
nth-last-child
Die Pseudo-Klasse :nth-last-child() ist das Gegenstück zum obigen :nth-child(). Der einzige Unterschied ist, dass die Elemente nicht vom ersten Element an durchgezählt werden, sondern vom letzten. nth-last-child(2n) wählt das vorletzte Element, das viertletzte, sechstletzte und so weiter.
nth-of-type und nth-last-of-type
Hierbei werden nicht die Kinder durchgezählt, sondern alle Elemente, die vor dem Doppelpunkt stehen. Und zwar bezogen auf das gesamte Dokument. Ein Beispiel:
<!-- HTML -->
<div>
<img title="erstes Bild im Dokument" />
<img title="zweites Bild im Dokument" />
<div>
<img title="drittes Bild im Dokument" />
</div>
</div>
<img title="viertes Bild im Dokument" />
Der Ausdruck img:nth-of-type(2n+1) würde demnach das erste und dritte Bild selektieren. Kindlichkeit wird nicht beachtet.
nth-last-of-type sollte mit der Kenntnis der Funktionsweise von nth-last-child selbsterklärend sein.
Die Browserfrage
Die Browsersituation ist übersichtlich aber unschön. Weder Firefox 3.0 noch der Internet Explorer 8 verstehen überhaupt eine der obigen Regeln. Der FF3.0 liegt ja zum Glück im Sterbebett darnieder; ob man beim IE9 auf umfassenden Structural pseudo-classes-Support hoffen kann, ist aber ungewiss.
Bei Konstrukten wie :nth-child(4) kann man sich mit dem Adjacent Sibling Selector (+) und :first-child zumindest teilweise helfen. Möchte man z.B. das vierte li einer Liste anwählen, verhilft ein kompliziertes li:first-child + li + li + li zum Glück.
Kommentare [2]
Tim am 8.11.2009 um 14:21
… der Ausdruck :nth-child(n-4) alle außer den ersten Vieren.
Das ist eine Ente. Wenn man bei diesem Ausdruck eine Wertetabelle anlegt, dann sind zwar für n=0 bis n=4 die Werte ≤ 0, für n=5 ist das Ergebnis 1, für n=6 ⇒ 2 usw. Das bedeutet, für jeden Wert > 0 gibt es ein n ≥ 0, bei dem die Gleichung stimmt. Deswegen würde ein :nth-child(n-4) alle Kinder selektieren.
Der richtige Ausdruck um alle Elemente ab dem Fünften auszuwählen ist deshalb
:nth-child(n+5)
Markus am 8.11.2009 um 14:50
Mist, falsch herum gedacht, stimmt. Der nächste Beitrag, der hier erscheint wird das noch mal etwas kritischer betrachten. Aber danke für den Hinweis, werde das einarbeiten.
Kommentar verfassen
Flattr
Blogrolle
- Björn Seibert
Webdesign & Rest - Christoph Koeberlin
Typographie verstehen - Der Spiegelfechter
Zeitgeschehen - Feynsinn
Politisches - Gerrit van Aaken
Webdesign & Rest - Jeffrey Zeldman
Jeffrey Zeldman eben - Mathias Schäfer
Webstandards & so - Nico Brünjes
ZEIT-Website-Mensch - Peter Kröner
Webdesign, Rants & Rest - Stefan Münz
Zur Zukunft und Gegenwart des Web
Podroll
- Boagworld
Paul Boag & Marcus Lillington - Chaosradio Express
Tim Pritlove und Gäste - Elektrischer Reporter
Aufklärung netzpolitischer Themen - Medienradio
Podcast über Medien (srsly!) - Read Between the Leading
Design allgemein - Technikwürze
Webdesign & Rest
Soziale Netzwerke
- Amazon-Wunschliste
Auf dass man mich reich beschenke - dasauge
Profil und Portfolio - Delicious
Social Bookmarking - Formspring.me
Obwohl schon alles über mich gesagt ist. - Google Reader Shared Items
Was ich lese und gut finde - last.fm
Meine Musik - Twitter
Lyrik & Prosa - Xing
Geschäftliches
Twitroll
- @font
Tobias Otte - @freshmango
Dennis Frank - @Herr_Gabriel
Gabriel Shahzad - @netzpolitik
Markus Beckedahl - @timpritlove
Tim Pritlove