Anfänger162025-01-15

CSS Pseudo-Classes - :hover, :focus, :nth-child & mehr

Lerne alle wichtigen CSS Pseudo-Classes: :hover, :active, :focus, :first-child, :last-child, :nth-child, :not und viele mehr für interaktive Designs.

#css#pseudo-classes#hover#focus#nth-child#selectors

CSS Pseudo-Classes

Pseudo-Classes stylen Elemente basierend auf ihrem Zustand oder Position. Mit einem Doppelpunkt : gekennzeichnet.

Was sind Pseudo-Classes?

Pseudo-Classes selektieren Elemente in einem bestimmten Zustand:

Pseudo-Class Syntax
selector:pseudo-class {
    property: value;
}

/* Beispiel */
a:hover {
    color: red;
}

Kein Extra-Element im HTML nötig!

Interaktions-Pseudo-Classes

:hover - Maus darüber

:hover - Mouse Over
/* Bei Maus-Hover */
a:hover {
    color: red;
    text-decoration: underline;
}

button:hover {
    background-color: #0056b3;
    transform: translateY(-2px);
}

.card:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
}

Häufigster Use Case: Feedback bei Interaktion

:active - Beim Klicken

:active - Click State
button:active {
    transform: scale(0.95);
    background-color: #004085;
}

a:active {
    color: darkred;
}

Moment des Klicks (Mausbutton gedrückt)

:focus - Fokus (Tastatur)

:focus - Keyboard Focus
/* Wenn fokussiert (Tab-Taste) */
input:focus {
    outline: 2px solid #007bff;
    border-color: #007bff;
}

button:focus {
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}

/* Focus sichtbar machen */
a:focus {
    outline: 2px solid #007bff;
    outline-offset: 2px;
}

Wichtig für Accessibility! Tastatur-User brauchen Fokus-Indicator.

:focus-visible - Smarter Focus

:focus-visible - Nur bei Tastatur
/* NUR bei Tastatur-Focus, NICHT bei Maus-Click */
button:focus-visible {
    outline: 2px solid #007bff;
}

/* Entfernt Outline bei Maus-Click */
button:focus:not(:focus-visible) {
    outline: none;
}

Modern & empfohlen: Zeigt Focus nur wenn nötig (Tastatur).

:focus-within - Fokus in Kind

:focus-within - Child Focus
/* Wenn irgendein Kind fokussiert ist */
.form-group:focus-within {
    background-color: #f0f8ff;
    border-color: #007bff;
}

.search-container:focus-within {
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}

Use Case: Form-Container highlighten wenn Input fokussiert.

Link-Pseudo-Classes

Spezielle States für Links:

Link States
/* Unbesuchter Link */
a:link {
    color: #007bff;
}

/* Besuchter Link */
a:visited {
    color: #6c757d;
}

/* Bei Hover */
a:hover {
    color: #0056b3;
    text-decoration: underline;
}

/* Beim Klicken */
a:active {
    color: #004085;
}

/* WICHTIG: Reihenfolge! */
/* LVHA = Link, Visited, Hover, Active */

Merkhilfe: LVHA (Love Hate)

Positions-Pseudo-Classes

:first-child / :last-child

First & Last Child
/* Erstes Kind */
li:first-child {
    font-weight: bold;
}

/* Letztes Kind */
li:last-child {
    border-bottom: none;
}

/* Praktisch: Spacing */
.card:last-child {
    margin-bottom: 0;  /* Kein Margin beim letzten */
}

:first-of-type / :last-of-type

First & Last of Type
/* Erstes p-Element */
p:first-of-type {
    font-size: 1.25rem;
}

/* Letztes p-Element */
p:last-of-type {
    margin-bottom: 0;
}

/* Unterschied zu :first-child: */
/* :first-of-type ignoriert andere Element-Typen */

:nth-child() - N-tes Kind

Mächtigster Positions-Selector:

:nth-child - Patterns
/* Jedes 2. Element (gerade) */
li:nth-child(even) {
    background-color: #f5f5f5;
}

/* Jedes 2. Element (ungerade) */
li:nth-child(odd) {
    background-color: white;
}

/* Spezifisches Element (3. Kind) */
li:nth-child(3) {
    color: red;
}

/* Jedes 3. Element */
li:nth-child(3n) {
    font-weight: bold;
}

/* Jedes 3. Element, ab dem 2. */
li:nth-child(3n+2) {
    color: blue;
}

/* Erste 3 Elemente */
li:nth-child(-n+3) {
    font-size: 1.2rem;
}

/* Alle außer erste 3 */
li:nth-child(n+4) {
    opacity: 0.7;
}

Formeln:

  • even = 2n (2, 4, 6, ...)
  • odd = 2n+1 (1, 3, 5, ...)
  • 3n = (3, 6, 9, ...)
  • 3n+1 = (1, 4, 7, ...)
  • -n+3 = (3, 2, 1) - erste 3
  • n+4 = (4, 5, 6, ...) - ab 4.

:nth-of-type()

:nth-of-type - Patterns
/* Jedes 2. p-Element */
p:nth-of-type(2n) {
    color: gray;
}

/* 3. p-Element */
p:nth-of-type(3) {
    font-weight: bold;
}

:only-child / :only-of-type

Only Child
/* Wenn einziges Kind */
li:only-child {
    list-style: none;
}

/* Wenn einziges p-Element */
p:only-of-type {
    text-align: center;
}

Form-Pseudo-Classes

:checked - Checkbox/Radio

:checked - Selected State
/* Checked Checkbox/Radio */
input[type="checkbox"]:checked {
    background-color: #007bff;
}

/* Custom Checkbox Style */
input[type="checkbox"]:checked + label {
    font-weight: bold;
    color: #007bff;
}

/* Radio Button */
input[type="radio"]:checked + label::before {
    background-color: #007bff;
}

:disabled - Deaktiviert

:disabled - Disabled State
input:disabled {
    background-color: #e9ecef;
    cursor: not-allowed;
    opacity: 0.6;
}

button:disabled {
    background-color: #6c757d;
    cursor: not-allowed;
}

button:disabled:hover {
    background-color: #6c757d;  /* Kein Hover-Effekt */
}

:enabled - Aktiviert

:enabled - Enabled State
input:enabled {
    border-color: #ced4da;
}

input:enabled:focus {
    border-color: #007bff;
}

:required / :optional

Required vs Optional
/* Pflichtfelder */
input:required {
    border-left: 3px solid #dc3545;
}

/* Optionale Felder */
input:optional {
    border-left: 3px solid #6c757d;
}

:valid / :invalid

Validation States
/* Gültige Eingabe */
input:valid {
    border-color: #28a745;
}

/* Ungültige Eingabe */
input:invalid {
    border-color: #dc3545;
}

/* Nur bei Interaktion zeigen */
input:not(:placeholder-shown):invalid {
    border-color: #dc3545;
}

:placeholder-shown

Placeholder State
/* Wenn Placeholder sichtbar (leer) */
input:placeholder-shown {
    border-color: #ced4da;
}

/* Wenn NICHT leer */
input:not(:placeholder-shown) {
    border-color: #28a745;
}

:in-range / :out-of-range

Range Validation
/* Für number/range inputs */
input[type="number"]:in-range {
    border-color: #28a745;
}

input[type="number"]:out-of-range {
    border-color: #dc3545;
}

:not() - Negation

Alles AUSSER:

:not() - Exclude
/* Alle li außer letztes */
li:not(:last-child) {
    border-bottom: 1px solid #dee2e6;
}

/* Alle Buttons außer disabled */
button:not(:disabled) {
    cursor: pointer;
}

button:not(:disabled):hover {
    background-color: #0056b3;
}

/* Mehrere Ausnahmen */
input:not([type="submit"]):not([type="button"]) {
    width: 100%;
}

/* Komplex */
div:not(.special):not(#unique) {
    color: gray;
}

:is() und :where() - Gruppierung

Moderne Selektoren für weniger Code:

:is() - Group Selectors
/* Alte Schreibweise */
h1:hover,
h2:hover,
h3:hover {
    color: red;
}

/* Mit :is() (gleicher Effekt) */
:is(h1, h2, h3):hover {
    color: red;
}

/* Komplex */
:is(.card, .panel) :is(h1, h2) {
    margin-bottom: 1rem;
}

:where() = gleich wie :is(), aber 0 Spezifität:

:where() - Zero Specificity
/* :where() hat keine Spezifität */
:where(h1, h2, h3) {
    color: blue;
}

h1 {
    color: red;  /* Gewinnt, weil :where() = 0 */
}

:empty - Leere Elemente

:empty - No Children
/* Leere divs verstecken */
div:empty {
    display: none;
}

/* Oder Nachricht anzeigen */
.list:empty::after {
    content: "Keine Einträge vorhanden";
    color: #6c757d;
}

:target - URL-Fragment

:target - URL Hash
/* Wenn Element über URL angesprungen */
/* URL: example.com#section1 */
#section1:target {
    background-color: #fff3cd;
    border-left: 4px solid #ffc107;
}

/* Smooth Scroll zu Target */
:target {
    scroll-margin-top: 80px;  /* Offset für Fixed Header */
}

Praktische Beispiele

Beispiel 1: Zebra-Stripes (Tabelle)

Zebra Stripes
table tbody tr:nth-child(odd) {
    background-color: #f8f9fa;
}

table tbody tr:nth-child(even) {
    background-color: white;
}

table tbody tr:hover {
    background-color: #e9ecef;
}

Beispiel 2: Card Grid ohne letzten Margin

No Last Margin
.card {
    margin-bottom: 20px;
}

.card:last-child {
    margin-bottom: 0;
}

/* Oder mit :not() */
.card:not(:last-child) {
    margin-bottom: 20px;
}

Beispiel 3: Custom Checkbox

Styled Checkbox
/* HTML */
<input type="checkbox" id="check1">
<label for="check1">Akzeptieren</label>

/* CSS */
input[type="checkbox"] {
    appearance: none;
    width: 20px;
    height: 20px;
    border: 2px solid #ced4da;
    border-radius: 4px;
    cursor: pointer;
}

input[type="checkbox"]:checked {
    background-color: #007bff;
    border-color: #007bff;
}

input[type="checkbox"]:checked::after {
    content: '✓';
    color: white;
    display: block;
    text-align: center;
}

input[type="checkbox"]:focus {
    outline: 2px solid #007bff;
    outline-offset: 2px;
}

Beispiel 4: Form Validation

Visual Form Validation
input {
    border: 2px solid #ced4da;
    padding: 10px;
    transition: border-color 0.3s;
}

/* Valid */
input:valid:not(:placeholder-shown) {
    border-color: #28a745;
}

input:valid:not(:placeholder-shown) + .icon {
    color: #28a745;
}

/* Invalid */
input:invalid:not(:placeholder-shown) {
    border-color: #dc3545;
}

input:invalid:not(:placeholder-shown) + .error {
    display: block;
    color: #dc3545;
}

/* Focus */
input:focus {
    border-color: #007bff;
    box-shadow: 0 0 0 3px rgba(0, 123, 255, 0.25);
}

Beispiel 5: Navigation Active State

Active Navigation
.nav-link {
    color: #6c757d;
    text-decoration: none;
    padding: 10px 15px;
    transition: color 0.3s;
}

.nav-link:hover {
    color: #007bff;
}

.nav-link:focus-visible {
    outline: 2px solid #007bff;
    outline-offset: 2px;
}

/* Active Link (mit Klasse oder :target) */
.nav-link.active,
.nav-link:target {
    color: #007bff;
    font-weight: 600;
    border-bottom: 2px solid #007bff;
}

Spezifität mit Pseudo-Classes

Pseudo-Classes erhöhen Spezifität:

Specificity
/* Element = 1 Punkt */
a {
    color: blue;
}

/* Element + Pseudo-Class = 11 Punkte */
a:hover {
    color: red;  /* Gewinnt! */
}

/* Klasse + Pseudo-Class = 20 Punkte */
.link:hover {
    color: green;  /* Gewinnt! */
}

Best Practices

✅ DO:

  1. :hover für visuelle Feedback
  2. :focus für Keyboard Accessibility
  3. :focus-visible statt :focus (modern)
  4. :nth-child für Patterns (Zebra-Stripes)
  5. :not() für Ausnahmen
  6. :checked für Custom Checkboxes
  7. Transitions für smooth State-Changes

❌ DON'T:

  1. Nicht :hover ohne :focus (Accessibility!)
  2. Nicht outline entfernen ohne Alternative
  3. Nicht zu spezifisch (einfach halten)
  4. Nicht :active ignorieren (Click-Feedback)
  5. Nicht :nth-child übertreiben (Lesbarkeit!)

📝 Quiz

Was ist der Unterschied zwischen :first-child und :first-of-type?

📝 Quiz

Wofür ist :focus-visible gut?

Tipps & Tricks

:is() für kompakte Selektoren

Vermeide Wiederholungen mit :is():

/* Statt */
h1:hover, h2:hover, h3:hover { color: blue; }

/* Nutze */
:is(h1, h2, h3):hover { color: blue; }

/* Auch verschachtelt */
:is(.card, .panel) :is(h1, h2) {
    margin-bottom: 1rem;
}

Spart Zeilen und verbessert Lesbarkeit!

Form-Validierung nur nach Interaktion

Zeige Fehler erst nach User-Input:

/* Nicht sofort rot beim Laden */
input:not(:placeholder-shown):invalid {
    border-color: #dc3545;
}

/* Oder nach Focus */
input:invalid:focus {
    border-color: #dc3545;
}

/* Success nach gültigem Input */
input:not(:placeholder-shown):valid {
    border-color: #28a745;
}

:has() für Parent Selektoren (Modern!)

Style Parent basierend auf Kindern:

/* Card mit Bild bekommt anderen Style */
.card:has(img) {
    display: grid;
    grid-template-columns: 1fr 2fr;
}

/* Form mit Fehler bekommt roten Border */
form:has(input:invalid) {
    border: 2px solid #dc3545;
}

/* Navigation wenn Link active ist */
nav:has(a.active) {
    background: #f0f0f0;
}

Game Changer für Parent-Styling!

Kombiniere Pseudo-Classes für Smart Spacing

Nutze :not(:last-child) für automatische Abstände:

/* Alle li außer letztes bekommen Border */
li:not(:last-child) {
    border-bottom: 1px solid #eee;
}

/* Alle Sections außer erste bekommen Margin */
section:not(:first-of-type) {
    margin-top: 3rem;
}

/* Cards mit Gap ohne letzten Margin */
.card:not(:last-child) {
    margin-bottom: 20px;
}

Übungsaufgaben

Aufgabe 1: Button States

Erstelle einen Button mit:

  • :hover (Farbe + translateY)
  • :active (scale)
  • :focus-visible (Outline)
  • :disabled (grau + cursor)

Aufgabe 2: Form Validation

Style ein Input-Feld:

  • :focus (blauer Border)
  • :valid (grüner Border)
  • :invalid (roter Border)
  • Nur nach Eingabe zeigen

Aufgabe 3: Zebra Table

Erstelle eine Tabelle mit:

  • :nth-child(odd) graue Rows
  • :hover hellblau
  • :first-child fett
  • :last-child kein Border

Nächste Schritte

Du kennst jetzt:

  • ✅ Interaktions-Pseudo-Classes (:hover, :active, :focus)
  • ✅ Positions-Pseudo-Classes (:first-child, :nth-child)
  • ✅ Form-Pseudo-Classes (:checked, :valid, :disabled)
  • ✅ :not(), :is(), :where()
  • ✅ Praktische Anwendungen

Als Nächstes lernst du:

  • Pseudo-Elements (::before, ::after)
  • Advanced Selectors
  • CSS Architecture

Weiter so! 🚀

CSSLektion 13 von 16
81% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "CSS Pseudo-Classes - :hover, :focus, :nth-child & mehr" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten