Übung 6 von 15 · Selektoren
Übung 6: Nur den ersten Listenpunkt hervorheben
Nur der erste Eintrag der Liste soll fett sein – ohne Klasse im HTML und ohne die anderen Einträge zu treffen.
<ul><li>Erster</li><li>Zweiter</li><li>Dritter</li></ul>
li { padding: 4px 0; } - ·erster Eintrag fett
- ·zweiter Eintrag normal
Hinweise
Hinweis 1
CSS 2.1 kennt eine Pseudoklasse für das erste Kind eines Elternelements.
Hinweis 2
li:first-child – das li, das erstes Kind seines ul ist.
Lösung
Lösung anzeigen
li:first-child { font-weight: bold; }:first-child trifft ein Element, das erstes Kind seines Elternelements ist. Für das letzte oder ein beliebiges n-tes Kind gibt es seit Selectors Level 3 :last-child und :nth-child(). Referenz: strukturelle Pseudoklassen.
Was first-child wirklich prüft
Die Pseudoklasse trifft ein Element, das das erste Kind seines Elternelements ist – nicht das erste Element seiner Art. Das ist der Unterschied, an dem die meisten Anwendungen scheitern: Steht vor dem gesuchten Element irgendein anderes Element, greift sie nicht, auch wenn das andere ein ganz anderer Typ ist.
Reiner Text und Kommentare zählen dabei nicht mit; nur Elemente. Ein Absatz nach einer Überschrift ist also nicht das erste Kind, ein Absatz nach einem Textknoten schon. In einer Liste ist der Fall eindeutig, weil dort nur Listenpunkte stehen dürfen – deshalb funktioniert die Aufgabe zuverlässig.
Für den anderen Fall gibt es seit Selectors Level 3 eine eigene Pseudoklasse, die auf das erste Element eines bestimmten Typs unter seinen Geschwistern zielt. Sie wird seltener gebraucht, als man denkt, ist aber genau dann die Antwort, wenn vor dem gesuchten Element etwas anderes stehen darf.
Warum keine Klasse im Dokument
Die Aufgabe verbietet die Klasse nicht aus Prinzip, sondern weil sie an dieser Stelle den falschen Ort hat. Eine Klasse beschreibt, was ein Element ist; hier ist die Bedingung eine reine Position, und die kennt der Browser bereits. Trüge das erste Element eine Klasse, müsste sie bei jeder Umsortierung mitwandern – von Hand oder im Programm, das die Liste erzeugt.
Genau das ist der Zweck der strukturellen Pseudoklassen: eine Bedingung, die sich aus dem Dokumentbaum ergibt, im Stylesheet auszudrücken statt im Dokument. Eine Liste, deren Einträge aus einer Datenquelle stammen, braucht dann keine Sonderbehandlung für den ersten.
Die Grenze ist erreicht, wo die Bedingung keine strukturelle ist. Ob ein Eintrag der wichtigste ist, ergibt sich nicht aus seiner Position – dafür ist eine Klasse richtig, und zwar eine, die die Bedeutung benennt und nicht das Aussehen.
Die Familie ringsum
Zur selben Familie gehören die Pseudoklassen für das letzte Kind, für ein einziges Kind ohne Geschwister und für ein beliebiges n-tes. Die letzte nimmt eine Formel entgegen: Die Schlüsselwörter für gerade und ungerade Positionen sind Kurzformen davon, und ein Ausdruck aus Vielfachem und Verschiebung trifft jede dritte, jede vierte oder alles ab dem vierten Element.
Gezählt wird dabei immer unter den Geschwistern, nicht unter den Treffern des Selektors. li.aktiv:nth-child(2) trifft also einen Listenpunkt, der zugleich die Klasse trägt und an zweiter Stelle steht – nicht den zweiten Listenpunkt mit dieser Klasse. Diese Verwechslung ist der zweite typische Fehler nach dem ersten oben.
Ein Zählen von hinten gibt es ebenfalls, mit einer eigenen Pseudoklasse. Zusammen decken sie fast jede Positionsbedingung ab, die im Alltag vorkommt – ausführlich in Selektoren ab Level 3.
Was die Pseudoklasse zur Spezifität beiträgt
Eine strukturelle Pseudoklasse zählt wie eine Klasse, also in der zweiten Position des Tupels. Ein Selektor aus Typ und Pseudoklasse wiegt damit so viel wie ein Selektor aus Typ und Klasse – der Verzicht auf die Klasse im Dokument kostet in der Kaskade nichts.
Bei den logischen Pseudoklassen ist es unterschiedlich, und das ist ihr eigentlicher Zweck. Die eine zählt so viel wie ihr stärkstes Argument, die andere in jedem Fall null. Letztere ist damit die einzige Möglichkeit, mehrere Selektoren zusammenzufassen, ohne die Spezifität anzuheben – nützlich für Grundregeln, die überall leicht zu überschreiben bleiben sollen.
Wer eine lange Selektorliste durch eine dieser Pseudoklassen ersetzt, sollte deshalb nachrechnen: Die Liste hatte für jeden Teil eine eigene Spezifität, die Zusammenfassung hat für alle die höchste. Aus einer harmlosen Aufzählung kann so unversehens eine Regel werden, die sich nur noch mit einer Kennung schlagen lässt. Die Übersicht dazu steht in Selektoren ab Level 3.
Für diese Aufgabe genügt der einfachste Selektor der Familie, und genau darin liegt ihr Punkt: Die Bedingung steckt schon im Dokumentbaum, sie muss nur ausgedrückt werden. Wer stattdessen eine Klasse setzt, verlagert eine Information, die der Browser hat, in eine Stelle, die jemand pflegen muss. Das ist die Regel, die auch bei den übrigen Pseudoklassen dieser Familie trägt – und der Grund, warum sie überhaupt in die Sprache aufgenommen wurden.
Wer die Liste später umsortiert oder einen Eintrag voranstellt, muss dabei nichts anfassen – die Hervorhebung wandert mit, weil sie an der Position hängt und nicht an einem Element.
Fragen zur Übung
Wie prüft die Übung das Ergebnis?
Der Prüfer rendert den eingegebenen Code in einem eigenen Rahmen und liest die berechneten Werte und Maße aus dem Rendering – nicht aus dem Quelltext. Jede Lösung, die dasselbe Rendering ergibt, gilt.
Wird der Fortschritt gespeichert?
Nur in diesem Browser, ohne Anmeldung. Gelöste Übungen bleiben markiert, bis der Browserspeicher gelöscht wird.