Selektoren in CSS/Einstieg

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Selektoren sind Muster, mit denen HTML-Elemente ausgewählt werden, damit man ihnen Stile zuweisen kann.

CSS-Regelsatz.svg

Der Selektor ist somit der Teil vor den geschweiften Klammern.

Einfache Selektoren

Universalselektor

Das Sternzeichen „*“ (der Asterisk) ist der Universalselektor. Mit ihm werden alle Elemente in einem Dokument angesprochen.

* - der Universalselektor ansehen …
* {
  border: medium solid green;
}
*, ::before, ::after { 
  box-sizing: border-box; 
}

Im Beispiel werden alle Elemente mit einer Randlinie versehen, was in der Praxis so niemand tun wird.

Mit dem Universalselektor kann man Elemente normalisieren, z. B. mit box-sizing das Box-Modell, das ja Randlinien zu den Breitenangaben dazuzählt, auf den intuitiveren QuirksMode umschalten.

In Verbindung mit anderen Selektoren ist der Universalselektor oft überflüssig. Auch erhöht er nicht die Spezifität des Selektors.

Typ-Selektor

Der Element- bzw. Typselektor besteht aus dem Namen des Elements, das angesprochen werden soll. Mit diesem Selektor werden alle Elemente eines Typs angesprochen.[1]

Typselektor ansehen …
h1 { 
  color: red; 
}
h1, h2 { 
  background-color: #ccc;
  border-radius: .5em; 
}

Der erste Regelsatz besteht aus einem Selektor h1, der allen h1-Elementen die Textfarbe rot zuweist.

Der zweite Regelsatz besteht aus einer Selektor-Liste mit zwei voneinander unabhängigen Selektoren h1 und h2, die alle Überschriften vom Typ h1 und h2 anspricht.

Klassen-Selektor

Häufig will man jedoch nicht alle, sondern nur eins oder einige Elemente speziell formatieren. In HTML, aber auch in SVG und MathML kann man Elementen ein Klassen-Attribut geben.

Ein Klassenselektor wird gebildet, indem vor dem Klassennamen ein Punkt notiert wird.

Klassen müssen nicht zu gleichen Elementen gehören ansehen …
.warning {
  background-color: #ffe0e0;
  border-left: thick solid #c82f04;
  padding: 0.5em;
  margin-bottom: 1em;
}

.example {
  background-color: #f9eed2;
  border-left: thick solid gold;
  padding: 0.5em;
  margin-bottom: 1em;
}

Die ersten drei Absätze erhalten Klassen und werden so formatiert. Allerdings erhält auch das div-Element die Klasse .warning und damit das Aussehen der Warnhinweise.

Beachte:
Klassennamen sollten nach ihrer Funktion (z.B. „Hinweis“) benannt werden und nicht nach den Formatierungen, die sie beinhalten. So stellen sie sicher, dass die Klasse auch nach einer Überarbeitung der Gestaltung noch nachvollziehbar den Bestandteilen eines Dokuments zugeordnet werden kann.
Viele informelle Eigenschaften eines Elements können durch elementspezifische Attribute abgedeckt werden. CSS erlaubt das Ansprechen von Elementen anhand ihrer Attribute. Klassen und Klassenselektoren sollten Sie daher nur dann einsetzen, wenn keine andere Zuordnungsmöglichkeit besteht.

ID-Selektor

Mit dem ID-Selektor kann ein Element angesprochen werden, dem eine ID mit dem id-Attribut zugeordnet wurde. Ein ID-Selektor wird gebildet, indem das Gatterzeichen „#“ vor den ID-Namen gestellt wird.

der Header - einzigartig ansehen …
#main-header {
  font-size: 1.8rem;
  color: navy;
  background-color: skyblue;
  padding: 1em;
  border: thin solid;
}

In oberem Beispiel erhält das Element h1 die ID „main-header“. Die CSS-Regeln bewirken, dass dieses einen hellblauen Hintergund, dunkelblaue Schriftfarbe und einen Rand erhält.

Beachte: Eine ID darf in einem Dokument nur ein einziges Mal vorkommen, die Kombination des ID-Selektors mit anderen Selektoren ergibt nur dann Sinn, wenn man die entsprechende ID in mehreren Dokumenten und in unterschiedlichen Situationen einsetzt.

Umgang mit IDs, die spezielle Zeichen enthalten

Aus Sicht von CSS ist eine ID ein CSS-Identifier und muss folgenden Regeln folgen:

  • Beginnt mit einem ASCII Buchstaben (A-Z, a-z)
  • Besteht im Übrigen aus den ASCII Zeichen a-z, A-Z, 0-9, "-" und "_", sowie allen Unicode-Zeichen ab U+0080.

Eine ID in HTML unterliegt wesentlich geringeren Einschränkungen. Während HTML 4 hier noch den Regeln von CSS ähnlich war, gibt es in HTML 5 fast gar keine Beschränkungen mehr, außer, dass eine ID kein Whitespace enthalten darf. Solche IDs können in CSS angesprochen werden, dafür müssen aber alle Zeichen, die die Regeln für CSS-Identifier verletzen, als CSS-Escape-Sequenz geschrieben werden.

Beispiel
<style>
#\31 234 {
  color: red;
}
</style>
...
<p id="1234">Dieser Text erscheint rot.</p>

Attribut-Selektor

CSS-Attributselektoren wählen Elemente aus, die ein bestimmtes Attribut explizit gesetzt haben, mit Optionen zur Definition einer Attributwert- oder Teilzeichenfolgenwertübereinstimmung.

Attributspräsenz

Ein Element, das ein bestimmtes Attribut besitzt, kann durch den einfachen Attribut-Selektor angesprochen werden, indem eckige Klammern („[“ und „]“) um den Namen des Attributs gesetzt werden.

Attributpräsenz
[aria-hidden] {
  opacity: 0.4;
  font-style: italic;
}

Alle Elemente, die ein aria-hidden Attribut haben, werden mit opacity ausgegraut.

Beachte: Ob die Groß- und Kleinschreibung des Attributnamens beachtet wird, hängt davon ab, ob man CSS für HTML oder für XML verwendet. Bei HTML wird sie nicht beachtet, bei XML (z. B. viewBox in SVG-Dokumenten) hingegen schon.

Selektion nach Wert

Attributselektoren erlauben es auch, nur diejenigen Elemente auszuwählen, bei denen ein Attribut einen bestimmten Wert besitzt:

Elemente nach Attributwerten selektieren ansehen …
button[aria-expanded="true"] {
  background-color: #d0f0d0;
  border-color: green;
}

button[aria-expanded="false"] {
  background-color: #f8e0e0;
  border-color: red;
}

button[aria-expanded="true"] + #myPopover {
  display: block;
}

Das button-Element erhält keine Klassen sondern ein aria-expanded-Attribut. Wenn dieser Button angeklickt wird, ändert sich der Wert seines aria-expanded-Attributs. Dies wird mit [aria-expanded="false"] bzw. [aria-expanded="true"] entsprechend selektiert und der Button ändert seine Farbe.

Der letzte Regelsatz button[aria-expanded="true"] + #myPopover verknüpft den Attributswert und die ID des nachfolgenden Elements mit einem Nachbar-Kombinator und lässt das Popover mit diplay:block erscheinen.

Beachte:
  • Der Vergleichswert muss entweder in Anführungszeichen gesetzt werden, oder den CSS-Namensregeln entsprechen. Wenn Du dir unsicher bist, setze einfach immer Anführungszeichen.
  • Ob die Groß- und Kleinschreibung des Attributwertes beachtet wird, hängt vom abgefragten Attribut ab. Die HTML Spezifikation listet diejenigen Attribute auf, bei denen die Schreibung nicht beachtet wird.[2] Dies sind typischerweise Attribute, deren Werte Schlüsselwörter darstellen. Bei allen anderen Attributen wird die Schreibung beachtet (z. B. id, class oder role).


Attributselektoren erlauben es auch, nur diejenigen Elemente auszuwählen, bei denen ein Attribut einen bestimmten Wert besitzt: oder einen bestimmten Wertabschnitt besitzt. Dafür erweitert man die einfache Präsenzabfrage um einen Vergleichsoperator und den Vergleichswert.

[name=wert] - vollständige Übereinstimmung
trifft nur auf diejenigen Elemente zu, deren Attribut exakt den angegebenen Wert hat.
[name~=wert] - Wert ist Teil einer durch Leerzeichen separierten Liste
trifft zu, wenn der genannte Wert Teil der Werteliste im Attribut name ist. Die Einträge dieser Liste müssen durch Leerzeichen getrennt sein. Ein Beispiel für ein solches Listenattribut ist class (wobei man Klassen natürlich besser mit dem Klassenselektor abfragt).
[name|=wert] - Übereinstimmung bis zum ersten --Zeichen
Der Selektor verhält sich ähnlich wie [name=wert], der Vergleich geht aber nur bis zum ersten --Zeichen im Attributwert. Ist kein --Zeichen enthalten, wird vollständig verglichen. Diese Art der Abfrage bietet sich beispielsweise für Sprachcodes (de-at) an.
[name^=wert] - Übereinstimmung mit dem Anfang des Attributwerts
trifft zu, wenn der Attributwert mit dem angegebenen Wert beginnt
[name$=wert] - Übereinstimmung mit dem Ende des Attributwerts
trifft zu, wenn der Attributwert mit dem angegebenen Wert endet
[name*=wert] - Übereinstimmung mit einem Teil des Attributwerts
trifft zu, wenn der Attributwert den angegebenen Wert an einer beliebigen Stelle enthält


PDFs mit Teilübereinstimmung-Selektor finden und stylen ansehen …
a[href$=".pdf"]:after {
  content: "";
  display: inline-block;
  width: 1.5em;
  aspect-ratio: 1;
  padding-left: 0.5em;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath ...");
  background-size: contain;
  background-repeat: no-repeat;
}

Im Beispiel finden sich zwei normale Links, die im href-Attribut auf PDF-Dokumente verlinken. Mit CSS werden sie über den Teilübereinstimmung-Selektor aufgrund der Dateiendung .pdf ([href$=".pdf"]) ausgewählt, das heißt selektiert.

Sie erhalten mit :after nun ein Pseudoelement, das als Hintergrundbild das PDF-Icon als SVG enthält.

HTML/Tutorials/Links
Links auf unterschiedliche Dokumenttypen kennzeichnen

Beachte: Gibt man als Wert innerhalb dieser Selektoren die leere Zeichenkette an (z. B. [attribut*=""]), spricht der Selektor kein Element an.
Beachte:
  • In HTML gibt es boolesche Attribute, denen kein Wert zugewiesen werden muss, z. B. das checked-Attribut bei input-Elementen.
    Prüfe solche Attribute nur auf Attributpräsenz, nicht auf einen Wert!
  • Ein boolesches Attribut stellt nicht immer den aktuellen Zustand eines Elements dar. Eine Checkbox mit dem Attribut checked, behält das Attribut, auch wenn die Checkbox abgewählt wird.
    Verwende die Pseudoklasse :checked. In einem <details>-Element stellt das open-Attribut hingegen dar, ob das Element aufgeklappt ist oder nicht.

case-Sensitivität

Wie schon erwähnt, ist für bestimmte Attributwerte in HTML die Groß- und Kleinschreibung relevant (case-sensitiv). Beispielsweise bezeichnen die Klassennamen foo und Foo verschiedene Klassen.

Man kann in Attributselektoren mithilfe des Flags i oder s festlegen, ob der Vergleich des Attributwertes – unabhängig von den Vorgaben des jeweiligen Attributes – unter Beachtung der Schreibweise stattfinden soll oder nicht. Den zu vergleichenden Attributwert muss man dann in Anführungszeichen notieren.

Beachte: Diese Flags wirken nur auf den ASCII-Zeichensatz, also a-z und A-Z. Akzentzeichen und Umlaute sind außerhalb des ASCII-Bereichs und werden stets case-sensitiv verglichen.
Beispiel ansehen …
[class="warning"] { 
  color: red;
}
[class="warning" i] {
  background-color: lightgray; 
}
<div class="warning">warning</div>
<div class="Warning">Warning</div>
<div class="WARNING">WARNING</div>

Nur im ersten div-Element ist die Schriftfarbe rot, weil nur dieses der Klasse warning angehört. Alle div-Elemente hingegen haben einen grauen Hintergrund.

Die i- und s-Flags kann man in allen Attributwertselektoren verwenden.

Anwendung

In der Praxis ist oftmals günstiger, Selektoren zu kombinieren, um trennscharf den gewünschten Stil festzulegen, ohne allen Elementen eine Klasse oder sogar eine ID zu geben, was der Idee hinter den „zentralen Formaten“ wiederspricht.

angeblicher Screenshot einer mit Bootstrap formatierten Seite

Empfehlung: Auch wenn dieser im Internet verbreitete Screenshot einer angeblich mit Bootstrap geschriebenen Seite wahrscheinlich nicht echt ist, sollte man die Verwendung einer Vielzahl präsentationsbezogener Klassen vermeiden!
Weniger ist mehr!

Verbundene Selektoren

Ein verbundener Selektor ist eine Kette von einfachen Selektoren, die nicht mit Hilfe eines Kombinators verkettet wurden. Verbundene Selektoren beginnen immer mit einem Typselektor oder dem Universalselektor, wobei der Universalselektor auch impliziert sein kann.

Zum Beispiel ist in .class[attribute] der Universalselektor implizit vorhanden: *.class[attribute]

Im weiteren Verlauf der Kette ist kein weiterer Typ- oder Universal-Selektor erlaubt.

Selektor-Listen

Eine Selektor-Liste ist eine komma-separierte Liste von beliebigen Selektoren. Die Selektorliste trifft auf ein Element zu, wenn mindestens einer der darin enthaltenen Selektoren auf das Element zutrifft.

Beispiel
h1 { font-family: sans-serif }
h2 { font-family: sans-serif }
h3 { font-family: sans-serif }
h1, h2, h3 { font-family: sans-serif }

Beide Beispiele setzen für die Überschriften 1., 2. und 3. Ordnung die Eigenschaft font-family auf den Wert sans-serif. Bei dem zweiten Beispiel handelt es sich um eine Selektor-Liste.

Dabei muss zwischen einer Selektor-Liste und einer fehlertoleranten Selektor-Liste (forgiving selector list) unterschieden werden. Wenn einer der Selektoren in einer Selektor-Liste fehlerhaft ist, gilt die ganze Liste als fehlerhaft und trifft auf kein Element mehr zu.

Wenn der Selektor einer CSS-Regel aus einer Selektorliste besteht, ist diese nicht fehlertolerant. Das kann ärgerlich sein, ist aber nicht mehr zu ändern, ohne ein CSS-Erdbeben auszulösen.

Aber: es gibt einige Pseudoklassen, die Selektorlisten verwenden. Es handelt sich um :is(), :where(), :has() und der of S-Erweiterung der indexbasierenden Pseudoklassen). Diese Selektorlisten sind fehlertolerant, oder waren es, bis es Beschwerden von jQuery gab. Dort existierte schon lange eine :has()-Pseudoklasse, und die strikt fehlertolerante Implementierung in Chromia warf jQuery auf die Nase. Chrome hat die fehlertolerante Implementierung von :has() deshalb zurückgezogen, und aus der Spezifikation wird sie auch verschwinden (Stand August 2025).

Die Frage, was ein Fehler ist, ist dabei nicht so ganz einfach zu beantworten. Ein unbekannter Elementtyp, wie h7 im folgenden Beispiel, ist kein Fehler. Eine unbekannte Pseudoklasse wie z.B. :final-child statt :last-child ist aber einer. Schließt man die Selektorliste in die Pseudoklasse :is() ein, die ihren Inhalt fehlertolerant behandelt, werden immerhin noch a-Elemente, die das erste Kindelement ihres Elternelements sind, blau gefärbt.

Fehlertolerante Selektorliste
/* Kein Fehler, Selektorliste für h1, h2, h3 zu */
h1, h2, h3, h7 { font-family: sans-serif }

/* Fehler, Selektorliste trifft niemals zu */
a:first-child, a:final-child { color: red; }

/* :is() ist fehlertolerant, :final-child wird ignoriert */
:is(a:first-child, a:final-child) { color: blue; }

Kombinatoren

Anstatt alle Elemente eines Typs zu stylen, kann man bestimmte Elemente nur dann ansprechen, wenn sie in bestimmten Kontexten auftreten – das ist übersichtlicher, intelligenter und vermeidet die übermäßige Verwendung von Klassen oder IDs.

Kombinatoren sind Zeichen, die zwei Selektoren (genauer: *verbundene Selektoren*) miteinander verketten. Durch diese Verkettung bildet der erste Teilselektor eine Bedingung und der zweite Teilselektor das Ziel, das angesprochen werden soll, wenn die Bedingung erfüllt wurde. Der Kombinator gibt dabei an, in welchem Verhältnis die Teilselektoren vor und nach ihm zueinander stehen müssen.

Zwischen zwei Selektoren kann nur ein Kombinator stehen, jedoch kann an diese Kette ein weiterer Kombinator zusammen mit einem weiteren Teilselektor angehängt werden.

Selektoren, die Kombinatoren enthalten, nennt man komplexe Selektoren.

Nachfahren-Kombinator

Werden zwei Selektoren durch ein  (Leerzeichen) verbunden, z. B. nav li, so wird das li-Element nur dann angesprochen, wenn es im DOM ein Nachfahre eines nav-Elements ist. Ein Element F ist Nachfahre eines Elements E, wenn man ausgehend von F der Kette der Elternelemente folgt und dabei auf E stößt. Das ist die allgemeinere Form einer Kindelement-Beziehung.

Stilfestlegung für em-Elemente, die Nachfahrenelemente von p sind. ansehen …
p em {
   color: green;
   padding: border: 1px solid;	
   background-color: #fffbf0;
   font-style: italic; 
}


In diesem Beispiel werden die beiden em-Elemente innerhalb des Absatzes mit grüner Schriftfarbe dargestellt, da es sich bei beiden um Nachfahrenelemente des p-Elements handelt. Das em-Element innerhalb der Überschrift ist kein Nachfahre des p-Elements, es ist deshalb nicht betroffen.

Beachte: Das Leerzeichen (bzw. ein anderes Whitespace-Zeichen) zwischen zwei Selektoren dient nur dann als Kombinator, wenn kein anderer Kombinator vorhanden ist.

Kind-Kombinator

Werden zwei Selektoren durch den Kind-Kombinator > (schließende spitze Klammer, Größer-Als-Zeichen) verbunden, z. B. ul > li, so wird das li-Element nur dann angesprochen, wenn es ein Kindelement eines ul-Elements ist. Ein Element F ist Kindelement von Element E, wenn das E das Elternelement von F ist.

Kind-Kombinator ansehen …
p > em {color: green;}
<h1> Der <em>Kind</em> selektor </h1> <p> <em>Dieses</em> Beispiel demonstriert die Wirkung des <del> <em>Nachbar</em> </del> Kindselektors. </p>

Das em-Element zu Beginn des p-Elements wird grün dargestellt, weil es ein direktes Kind des p-Elements ist. Für die beiden anderen em-Elemente gilt das nicht. Das erste befindet sich in der h1-Überschrift und hat überhaupt kein p-Element in seiner Elternkette. Das em-Element innerhalb des del-Elements ist zwar Nachfahre eines p-Elements, aber kein direktes Kind, sondern sozusagen ein Enkel. Deshalb werden diese beiden em-Elemente nicht grün und erben die Schriftfarbe ihres Elternelements.

Nachbar-Kombinator

Werden zwei Selektoren durch den Nachbar-Kombinator + (Pluszzeichen) verbunden, z. B. E + F, so wird das Element F nur dann angesprochen, wenn es im Elementbaum direkt auf ein E-Element folgt, also der direkte Nachbar ist.

Beispiel ansehen …
h1 + p { font-weight: bold }
p + p { font-style: italic }
<h1>Nachbarkombinator</h1>
<p>Erster Absatz.</p>
<p>Zweiter Absatz.</p>
<p>Dritter Absatz.</p>
<div>neutrales Element</div>
<p>Vierter Absatz</p>

In diesem Beispiel wird der erste Absatz mit fett formatierter Schrift dargestellt, denn es ist das einzige unmittelbare Nachbar-p-Element von h1.

Für den zweiten und dritten Absatz gilt: Sie sind Nachbar-p-Elemente je eines p-Elements. Sie werden also kursiv dargestellt.

Der vierte Absatz ist ein Nachbar eines neutralen div-Elements und wird nicht gestylt.

Beachte: Eine Selektion des vorangehenden Elements ist nicht möglich, evtl. hilft hier die Pseudoklasse focus-within, die selektiert, wenn ein Kindelement oder Nachfahre den Fokus erhält.

lobotomized owl selector

Der Selektor * + * wird lobotomized owl selector genannt, weil er den „Erfinder“ an eine Eule erinnerte.[3]

Er selektiert alle Elemente, denen auf der selben Ebene ein Geschwisterelement vorausgeht, also alle Elemente, die nicht das erste Kind sind.

Mithin ist er gleichbedeutend zu html :not(:first-child), aber kürzer und performanter. (Der Selektor :not(:first-child) würde auch das Wurzelelement selektieren, welches ja kein Kind ist.)

Geschwister-Kombinator

Werden zwei Selektoren durch den Geschwister-Kombinator ~ (Tilde) verbunden, z. B. E ~ F, so werden alle F-Elemente angesprochen, die im Elementbaum in derselben Ebene auf ein E-Element folgen – unabhängig davon, ob sich zwischen den Elementen weitere, im Selektor nicht genannte, Elemente befinden.

Beispiel ansehen …
h1 ~ p {font-weight: bold;}
<p>Erster Absatz.</p>
<h1>Der Geschwisterselektor</h1>
<p>Zweiter Absatz.</p>
<hr>
<p>Dritter Absatz.</p>

In diesem Beispiel werden sowohl der zweite als auch der dritte Absatz mit fett formatierter Schrift dargestellt, da beide Elemente auf das h1-Element folgen. Die Trennlinie zwischen den beiden Absätzen verhindert dies nicht. Einzig der erste Absatz wird mit normaler Schrift dargestellt, da er vor dem bedingenden h1-Element steht.

relative Selektoren

An einigen Stellen müssen Selektoren notiert werden, die mit anderen Selektoren kombiniert werden müssen, damit das gewünschte Ergebnis erzieht wird. Ein Beispiel ist die :has()-Pseudoklasse, mit der man abfragen kann, ob ein Element bestimmte andere Elemente enthält. Innerhalb von :has() muss ein Selektor notiert werden, der die zu prüfenden Elemente beschreibt, und dieser Selektor gilt nur in Bezug auf den Selektor, dem :has() zugeordnet ist – er ist relativ zu diesem Selektor.

CSS löst das so, dass der äußere Selektor und der innere Selektor mit einem Kombinator verbunden werden. Dies ist standardmäßig der Nachfahrenselektor (das Leerzeichen). Wenn Sie einen anderen Kombinator verwenden möchten, müssen Sie diesen innerhalb von :has() notieren, was zu ungewohnten Schreibweisen wie :has(> .foo) oder :has(~ ul) führt.

Kurz gesagt: Relative Selektoren sind Selektoren, die mit einem Kombinator beginnen

Weil die Leerstelle den Nachfahrenselektor bildet, folgt daraus, dass :has(div) den relativen Selektor   div enthält.

Selektoren, deren Bezugspunkt das Wurzelelement des Dokuments ist, nennt man dementsprechend absolute Selektoren.

Auch CSS-Schachtelung verwendet relative Selektoren. Sobald der Selektor einer geschachtelten Regel den &-Selektor enthält, setzt CSS dort den Selektor der Elternregel ein und man erhält einen absoluten Selektor. Fehlt das &, handelt es sich um einen relativen Selektor, der sich auf den Selektor der Elternregel bezieht.

Siehe auch


Weblinks

  1. Typselektoren können auch um eine Namensraum-Angabe erweitert werden. Näheres dazu findest du im Artikel zu CSS Namensräumen.
  2. WHATWG HTML Spezifikation: Attribute, bei denen die Schreibung des Wertes nicht beachtet wird
  3. A List Apart: axiomatic css and lobotomized owls