Zum Inhalt springen
HTML & CSS Anfänger 25 min

Pseudo-Klassen & Pseudo-Elemente

Lerne CSS Pseudo-Klassen wie :hover, :focus, :has() und Pseudo-Elemente wie ::before und ::after kennen.

Aktualisiert:

Pseudo-Klassen & Pseudo-Elemente

Pseudo-Klassen und Pseudo-Elemente erweitern CSS um zusaetzliche Auswahlmoeglichkeiten, die mit normalen Selektoren nicht moeglich waeren. Sie sind unverzichtbar fuer interaktive und dekorative Styles.

Pseudo-Klassen: Zustaende auswählen

Pseudo-Klassen waehlen Elemente basierend auf ihrem Zustand oder ihrer Position aus. Sie beginnen mit einem Doppelpunkt (:).

Interaktive Pseudo-Klassen

/* Link wurde noch nicht besucht */
a:link { color: #264de4; }

/* Link wurde bereits besucht */
a:visited { color: #7b2d8e; }

/* Maus schwebt ueber dem Element */
a:hover { color: #e44d26; }

/* Element ist aktiv (wird gerade geklickt) */
a:active { color: #c0392b; }

/* Element hat den Fokus (Tab-Navigation) */
a:focus {
    outline: 2px solid #264de4;
    outline-offset: 2px;
}

/* Fokus nur bei Tastatur-Navigation */
a:focus-visible {
    outline: 2px solid #264de4;
    outline-offset: 2px;
}

Wichtig: Die Reihenfolge bei Links muss sein: :link, :visited, :hover, :active (LVHA).

:focus-visible vs. :focus

/* :focus -- bei JEDEM Fokus (auch Mausklick) */
button:focus {
    outline: 2px solid blue;
}

/* :focus-visible -- nur bei Tastatur-Navigation */
button:focus-visible {
    outline: 2px solid blue;
}

/* Modernes Pattern: */
button:focus { outline: none; }
button:focus-visible {
    outline: 2px solid #264de4;
    outline-offset: 2px;
}

Formular-Pseudo-Klassen

/* Aktiviertes/Deaktiviertes Feld */
input:enabled { background: white; }
input:disabled { background: #e2e8f0; opacity: 0.6; }

/* Ausgewaehlte Checkbox/Radio */
input:checked + label {
    font-weight: bold;
    color: #e44d26;
}

/* Pflichtfeld */
input:required { border-left: 3px solid #e44d26; }
input:optional { border-left: 3px solid #e2e8f0; }

/* Gueltiger/Ungueltiger Wert */
input:valid { border-color: #10b981; }
input:invalid { border-color: #ef4444; }

/* Platzhalter wird angezeigt */
input:placeholder-shown {
    border-style: dashed;
}

Position-basierte Pseudo-Klassen

/* Erstes und letztes Kind */
li:first-child { font-weight: bold; }
li:last-child { margin-bottom: 0; }

/* Bestimmtes Kind */
li:nth-child(3) { color: #e44d26; }  /* Drittes Element */

/* Jedes zweite Kind (gerade) */
tr:nth-child(even) { background: #f8fafc; }

/* Jedes zweite Kind (ungerade) */
tr:nth-child(odd) { background: white; }

/* Jedes dritte Element */
li:nth-child(3n) { border-bottom: 2px solid #e44d26; }

/* Die letzten drei Elemente */
li:nth-last-child(-n+3) { color: #999; }

/* Einziges Kind */
p:only-child { font-size: 1.2rem; }

/* Leeres Element */
div:empty { display: none; }

Die :not() Pseudo-Klasse

/* Alle Absaetze AUSSER die mit Klasse "intro" */
p:not(.intro) {
    color: #666;
}

/* Alle Inputs ausser disabled */
input:not(:disabled) {
    cursor: pointer;
}

/* Alle Links ausser die aktive Seite */
nav a:not(.active) {
    opacity: 0.7;
}

/* Kombination */
li:not(:last-child) {
    border-bottom: 1px solid #e2e8f0;
}

Moderne Pseudo-Klassen

:has() — Der “Eltern-Selektor”

:has() waehlt ein Element, das ein bestimmtes Kind oder Nachbar hat:

/* Card MIT Bild anders stylen */
.card:has(img) {
    padding-top: 0;
}

/* Card OHNE Bild */
.card:not(:has(img)) {
    padding: 2rem;
}

/* Formular mit ungueltigen Feldern */
form:has(input:invalid) .submit-btn {
    opacity: 0.5;
    pointer-events: none;
}

/* Label-Farbe aendern wenn Input fokussiert */
label:has(+ input:focus) {
    color: #e44d26;
}

/* Sidebar ausblenden wenn kein aside-Element */
.layout:not(:has(aside)) main {
    grid-column: 1 / -1;
}

:is() und :where()

/* :is() -- gruppiert Selektoren (behaelt Spezifitaet) */
:is(h1, h2, h3):hover {
    color: #e44d26;
}

/* Verschachtelt: Alle Links in header, main, footer */
:is(header, main, footer) a {
    color: #264de4;
}

/* :where() -- gleich wie :is(), aber Spezifitaet = 0 */
:where(h1, h2, h3) {
    font-family: Georgia, serif;
    /* Leicht zu ueberschreiben */
}

Pseudo-Elemente: Virtuelle Elemente

Pseudo-Elemente erstellen virtuelle Elemente, die im HTML nicht existieren. Sie beginnen mit zwei Doppelpunkten (::).

::before und ::after

/* Text VOR dem Element einfuegen */
.required-label::after {
    content: " *";
    color: #ef4444;
}

/* Dekoratives Element */
.fancy-title::before {
    content: "";
    display: block;
    width: 50px;
    height: 3px;
    background: #e44d26;
    margin-bottom: 0.5rem;
}

Wichtig: content ist bei ::before und ::after Pflicht, auch wenn es leer ist (content: "").

Praktische ::before/::after Beispiele

/* Externe Links markieren */
a[href^="http"]::after {
    content: " ↗";
    font-size: 0.8em;
}

/* Zitat-Anfuehrungszeichen */
blockquote::before {
    content: "\201E";  /* Oeffnendes Anfuehrungszeichen */
    font-size: 3rem;
    color: #e44d26;
    line-height: 0;
}

/* Tooltip */
.tooltip {
    position: relative;
}

.tooltip::after {
    content: attr(data-tooltip);
    position: absolute;
    bottom: 100%;
    left: 50%;
    transform: translateX(-50%);
    background: #1a1a2e;
    color: white;
    padding: 0.5rem 1rem;
    border-radius: 4px;
    font-size: 0.875rem;
    white-space: nowrap;
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.2s;
}

.tooltip:hover::after {
    opacity: 1;
}

/* Dekorative Linie */
.section-title {
    position: relative;
    display: inline-block;
}

.section-title::after {
    content: "";
    position: absolute;
    bottom: -5px;
    left: 0;
    width: 100%;
    height: 3px;
    background: linear-gradient(to right, #e44d26, transparent);
}

Andere Pseudo-Elemente

/* Erste Zeile eines Absatzes */
p::first-line {
    font-weight: bold;
    color: #1a1a2e;
}

/* Erster Buchstabe */
p::first-letter {
    font-size: 2em;
    float: left;
    margin-right: 0.25rem;
    color: #e44d26;
    font-weight: bold;
}

/* Markierter Text (Selektion) */
::selection {
    background: #e44d26;
    color: white;
}

/* Platzhalter-Text */
input::placeholder {
    color: #94a3b8;
    font-style: italic;
}

/* Scrollbar stylen (Chromium) */
::-webkit-scrollbar {
    width: 8px;
}

::-webkit-scrollbar-track {
    background: #f1f1f1;
}

::-webkit-scrollbar-thumb {
    background: #888;
    border-radius: 4px;
}

Pseudo-Klassen und Pseudo-Elemente kombinieren

/* Erstes <li> mit speziellem Marker */
li:first-child::before {
    content: "★ ";
    color: #f59e0b;
}

/* Hover-Effekt mit Pseudo-Element */
.btn {
    position: relative;
    overflow: hidden;
}

.btn::before {
    content: "";
    position: absolute;
    top: 0;
    left: -100%;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.2);
    transition: left 0.3s ease;
}

.btn:hover::before {
    left: 0;
}

Uebungen

Uebung 1: Formular-Styling

Style ein Formular mit:

  • :focus-visible fuer Tastatur-Navigation
  • :valid und :invalid fuer Feedback
  • ::placeholder Styling
  • ::after fuer Pflichtfeld-Markierung

Uebung 2: :has() Experimente

Erstelle Cards, die sich basierend auf ihrem Inhalt anders stylen:

  • Cards mit Bild: kein oberes Padding
  • Cards mit Button: anderer Hintergrund
  • Leere Cards: versteckt

Uebung 3: Dekorative Elemente

Erstelle dekorative Elemente nur mit ::before und ::after:

  • Abschnittstrennlinien
  • Angemessene Anfuehrungszeichen fuer Zitate
  • Tooltip bei Hover

Was kommt als Naechstes?

Im naechsten Kapitel lernst du die modernsten CSS Features von 2026:

  • Container Queries im Detail
  • Subgrid
  • Scroll-gesteuerte Animationen
  • Und weitere Neuheiten

Zusammenfassung

  • Pseudo-Klassen (:hover, :focus, :nth-child) waehlen Elemente nach Zustand oder Position
  • :focus-visible zeigt Fokus nur bei Tastatur-Navigation
  • :has() ist der lang ersehnte “Eltern-Selektor” — extrem maechtig
  • :is() und :where() gruppieren Selektoren elegant
  • Pseudo-Elemente (::before, ::after) erstellen virtuelle Elemente
  • ::before und ::after brauchen immer die content-Eigenschaft
  • ::first-letter und ::first-line stylen Textteile

Pro-Tipp: Die :has() Pseudo-Klasse ist ein Game-Changer! Damit kannst du endlich Eltern-Elemente basierend auf ihren Kindern stylen — etwas, das CSS-Entwickler jahrelang vermisst haben. Experimentiere damit, denn sie wird die Art, wie wir CSS schreiben, grundlegend veraendern!

Zurück zum HTML & CSS Kurs