hover, visited, focus, link – CSS Pseudoklassen für Links
CSS-Pseudoklassen sprechen Interaktivität, Zustände oder besondere Elemente an. hover, link, active, focus und visited erreichen HTML-Objekte, die so im Dokument gar nicht vorkommen. Sie registrieren Aktionen des Benutzers, reagieren auf den Zustand von Eingabefeldern in Formularen und auf die Position eines Elements.
Elemente ohne spezielles HTML: Zustände von Links
Seit den Anfangstagen von HTML verwenden die Browser standardmäßig vier Hauptzustände für Links, die am besten in der dieser Reihenfolge angeben werden: Link → Visited → Hover → Active (LVHA-Regel).
| Pseudoklasse | Funktion |
|---|---|
:link |
Unbesuchte Links stylen |
:visited |
Besuchte Links anders färben |
:hover |
Maus-Hover-Effekt hinzufügen |
:active |
Stil ändern, wenn Link gerade geklickt wird |
:focus |
Wichtig für die Tastaturnavigation: Zeigt die Aktivierung an |
:target |
Ankerpunkte hervorheben |
Pseudo-Klassen entstehen bei Phantom-Zuständen eines Elements, meist durch Benutzeraktionen, aber auch bei bestimmten Sprachen und basieren auf Informationen außerhalb des DOM-Baums. Pseudo-Klassen können an beliebigen Stellen der Selektor-Kette stehen (ein Pseudo-Element wie ::before oder ::after hingegen nicht).
Pseudo-Klassen ansprechen
Im HTML-Code können diese Elemente gar nicht erreicht werden, denn es gibt kein HTML-Tag für „beim Hovern“ oder „hier warst du schon mal“. Also kann die Darstellung nicht durch ein style-Attribut beeinflusst werden.
E:any-link
Jedes a-, area oder link-Element mit href-Attribut, das einen Link darstellt, gleich, ob der Link schon besucht wurde oder nicht.
a:link { text-decoration: none; color: purple; }E:link
Alle Elemente E, die ein Hyperlink zu einem noch nicht besuchten Ziel sind
a:link { text-decoration: none; color: purple; }E:visited
Alle Elemente E, die ein Hyperlink zu einem bereits besuchten Ziel sind
a:visited { text-decoration: none; color: purple; }E:active
Während das Element E aktiv ist (z.B. Maustaste auf einen Link gedrückt ist).
a:active { background-color: #8FBC8F }E:hover
Während die Maus über dem Element E hovert
li:hover { background-color: #8FBC8F }E:focus
Während der Fokus auf dem Element E liegt
input:focus { background-color: lavender }Pseudo-Klassen für Links: die LVHA-Regel
Link-Pseudo-Klassen fangen die Zustände eines Links ab: Maus liegt über dem Link, Link wurde schon besucht. Diese CSS-Eigenschaften wurden schon früh von allen Browsern unterstützt.
- normaler Link (a:link) → blau (#0000EE)
- besuchter Link (a:visited) → violett (#551A8B)
- aktiver Link (a:active) → rot (#FF0000)
- hover → kein fester Standard, aber de facto ein helleres Blau oder unterstrichen
- focus → wird von Browsern nativ durch einen Focus Ring (oft blau, manchmal gestrichelt) hervorgehoben; keine fixierte Farbe im Standard
Text gestalten (Besuchter Link – simuliert)
Positionieren (Aktiver Link – kurzzeitig bei Klick sichtbar)
2023 sind die Systemfarben hinzugekommen und werden von den modernen Browsern zuverlässig unterstützt. Diese Farben passen sich automatisch an das Erscheinungsbild an: Light Mode, Dark Mode.
CSS2 erlaubt eine weitere Differenzierung, bei der die Pseudo-Klassen hintereinander geschaltet sind.
a:visited:hover { background-color: gray; color: white }
Die Reihenfolge der Pseudo-Selektoren muss wie hier :link, :visited, :hover, :focus, :active sein (LVHA-Regel). Ansonsten überschreibt z.B. :visited den Selektor :hover.
Tap statt Hover für Touchscreens
Ein :hover-Selektor sollte nicht ohne Weiteres für wichtige Aktionen eingesetzt werden, denn auf Smartphones und Tabletts gibt es kein :hover. Deshalb erkennt der Nutzer oft nicht, dass ein Bild interaktiv ist. Der Finger toucht ein Element oder tippt es doppelt – aber es gibt kein Überstreichen wie mit der Maus.
Tabletts und Smartphones übersetzen ein hover über einem Link direkt in einen Mausklick.
Wenn :hover für Animationen eingesetzt wird – z.B. einen Link anzeigen, wenn die Maus über einem Bild hovert –, kann Javascript den Effekt beim Berühren des Elements für Touchscreens nachziehen. Dann sind Javascript-Events wie ontouchstart und ontouchend das Äquivalent zum Hovern mit der Maus oder – die moderneren und flexibleren Javascript Pointer-Events.
Da heute Besucher mit den Touchscreen überwiegen, kann man überlegen, wie sinnvoll der Einsatz von :hover überhaupt noch ist und lieber sowohl für Desktop als auch für den Touchscreen der mobilen Geräte ein Tap einsetzen. Mit einem Tap kann der Benutzer auch steuern, welcher Teil des Bildes des Bildes gezoomt werden soll.
.tap-zoom {
position: relative;
overflow: hidden;
cursor: zoom-icon;
}
.tap-zoom img {
width: 100%;
height: auto;
transition: transform .35s ease;
transform-origin: center;
}
.tap-zoom.zoomed img {
transform: scale(2);
}
Für das tap-zoom ist ein kleines Stück Javascript zuständig. 13 Zeilen – überschaubar.
document.querySelectorAll(".tap-zoom").forEach(el => {
let zoomed = false
el.addEventListener("click", e => {
zoomed = !zoomed;
el.classList.toggle("zoomed", zoomed);
if (zoomed) {
const rect = el.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width * 100;
const y = (e.clientY - rect.top) / rect.height * 100;
el.querySelector("img").style.transformOrigin = `${x}% ${y}%`;
}
});
});
getBoundingClientRect liefert die Position (top, left, bottom, right) sowie Breite und Höhe eines Elements im Browserfenster / Viewport.
hover – nicht nur bei Links
Früher unterstützten die meisten Browser das Ändern einer CSS-Eigenschaft beim Hovern mit der Maus nur bei a-Tags. Heute klappt es auch mit anderen HTML-Elementen: Listen, Tabellenzellen und Texte in Absätzen.
| Krefeld | 222.500 | 2015 | 137,0 km2 |
| Moers | 102.923 | 2015 | 67,68 km2 |
| Duisburg | 485.465 | 2015 | 232,8 km2 |
| Düsseldorf | 604.527 | 2015 | 217,4 km2 |
@media (max-width:360px) {
td:nth-child(3) { display:none}
}
tr:nth-child(odd) {background: gainsboro;}
tr:hover { background: ivory}
So erhalten z.B. Tabellenzeilen mit tr : hover einen farbigen Hintergrund, wenn die Maus über ihnen hovert und die Navigationsleiste zeig ein Pull-Down oder – wie hier – ein Fly-Out-Menü.
Aber wie oben unter Die hover-Falle: Auf dem Touchscreen – dem Tablett und dem Smartphone – gibt es kein :hover.
Eine Navigation darf darum nicht mehr ohne Erkennung von Touch Devices auf :hover beruhen. Ein responsives Menü für die Navigation kann ohne Javascript, nur mit HTML und CSS animiert werden.
ul.col ul {
display: none
}
ul.col li:hover ul {
list-style: none;
display: block; position: absolute;
left: 14em; z-index: 10; margin-top: -2em;
width: 12em
}
So kommen wir dann mit CSS an eine aufpoppende Navigation ganz ohne Javascript. Das funktioniert auch in Internet Explorer.
any-link
any-link wirkt auf linkende Elemente (Elemente mit einem href-Attribut), egal, ob der Link schon besucht oder noch nicht besucht wurde.
Stile für :any-link wirken z.B. auch, wenn ein a-Element einen Block von Elementen umspannt: Mit HTML5 darf ein a-Tag um ein oder mehrere Block-Elemente gelegt werden.
HTML
<a href="/tutorial/css-tabs.html">
<h4>CSS Tabs ohne Javascript</h4>
<p>Tabs nur mit HTML input, … </p>
</a>
:focus
Focus wird anders behandelt als die Link-Zustände. Die Pseudoklasse :focus entdeckt, ob ein Feld aktiviert ist – entweder durch einen Klick mit der Maus in das Feld oder durch eine Navigation mit dem Tabulator der Tastatur. Es gibt keine vorgegebene FokusText-Farbe, sondern einen Fokus-Ring – das Feld wird durch einen besonderen Rahmen markiert (outline)
input#name:focus { background-color: Highlight }
focus mit Attribut-Selektor
input[type="password"]:focus { background-color: Highlight }
Wenn das Eingabefeld in den Fokus kommt, wird es farbig hinterlegt.
Pseudo-Klassen vs Pseudo-Elemente (einfacher oder doppelter Doppelpunkt)
Pseudo-Elemente sprechen Teile eines Elements ohne HTML-Markup an, z.B. die erste Zeile eines Absatzes (::firstLine) und können Elemente ohne HTML-Markup einfügen (::before, ::after) oder einfach nur stylen (::marker – die Marker-Box von Listen). Sie können nicht inline in einem style-Attribut vereinbart werden und nur am Ende der Selektor-Kette stehen.
Sowohl Pseudo-Klassen als auch Pseudo-Elemente können nicht inline in das HTML-Element gesetzt werden – denken wir einmal an ein hover.
Benutzeraktionen
- :popover-open
- wenn ein Popover oder <dialog> offen ist
- :modal
- wenn ein Popover oder <dialog> offen ist
- :hover
- wenn ein <dialog> gerade als modal angezeigt wird.
- :active
- während das Element aktiv geklickt/gedrückt wird.
- :focus
- wenn das Element den Tastaturfokus hat.
- :focus-visible
- Fokus sichtbar, wenn es für den Nutzer sinnvoll ist (z. B. per Tab).
- :focus-within
- wenn ein Kindelement den Fokus hat.
- :visited
- für bereits besuchte Links (<a>).
- :link
- für nicht besuchte Links.
- :target
- wenn ein Element über #anker angesprungen wurde.
- :enabled
- für aktivierte Formularelemente.
- :disabled
- für deaktivierte Formularelemente.
- :checked
- für Checkboxen, Radiobuttons, Switches, wenn aktiv.
- :indeterminate
- für Checkboxen, wenn weder an- noch abgewählt.
- :valid /
- :invalid
- je nach Gültigkeit einer Formulareingabe.
- :required /
- :optional
- Pflichtfelder oder optionale Felder im Formular.
- :read-only /
- :read-write
- ob Eingabe erlaubt ist.
- :autofill
- wenn ein Browser ein Feld automatisch ausgefüllt hat.
- :placeholder-shown
- solange ein Placeholder sichtbar ist.
Strukturelle Pseudoklassen – Position im Dokument
- :first-child
- erstes Kindelement.
- :last-child
- letztes Kindelement.
- :only-child
- wenn ein Element das einzige Kind ist.
- :nth-child(n)
- das n-te Kindelement.
- :nth-last-child(n)
- das n-te Kindelement von hinten.
- :first-of-type
- erstes Element eines Typs (z. B. erstes <p>).
- :last-of-type
- letztes Element eines Typs.
- :only-of-type
- wenn es das einzige Element seines Typs ist.
- :nth-of-type(n)
- n-tes Element seines Typs.
- :nth-last-of-type(n)
- n-tes Element seines Typs von hinten.
- :empty
- wenn das Element keine Kinder (auch keinen Text) hat.
- :not(selector)
- Negation
- : wählt alle außer die angegebenen.
- :is(selector, …)
- Kurzschreibweise für mehrere Selektoren.
- :where(selector, …)
- wie
- :is, aber ohne Gewichtung für Spezifität.
- :has(selector)
- Parent-Selector (wählt ein Element, wenn es ein bestimmtes Kindelement enthält).
Pseudo-Elemente
- ::first-line
- erste Zeile eines Textblocks.
- ::first-letter
- erster Buchstabe.
- ::selection
- der Bereich, den der Nutzer markiert hat (z. B. Farbe ändern).
- ::spelling-error
- markiert Rechtschreibfehler (wenn vom Browser erkannt).
- ::grammar-error
- markiert Grammatikfehler.
- ::placeholder
- Platzhaltertext in Input/Textarea stylen.
- ::file-selector-button
- der Button von .
- ::marker
- die Marker von Listen (•, 1., - …).
- ::cue /
- ::cue-region
- Untertitel in
- ::backdrop
- Hintergrund von geöffneten Dialogen oder Vollbild-Elementen.
- ::part(name)
- gezieltes Stylen von Shadow-DOM-Parts.
- ::slotted(selector)
- Styles auf Slots im Shadow DOM.
- ::highlight(name)
- benutzerdefinierte Text-Hervorhebung.
- ::target-text
- den Text hervorheben, der über #textfragment angesprungen wurde.
- ::view-transition-old / ::view-transition-new
- für Seitenübergänge (Page Transitions API).
Pseudo-Klassen werden durch einen Doppelpunkt vom Selektor getrennt: a:hover oder li.activeItem:hover. Dabei darf kein Leerzeichen zwischen dem Element und dem Doppelpunkt stehen.
:hover und :focus sind dynamische Pseudo-Klassen, mit denen CSS auf Benutzeraktionen wie das Hovern mit der Maus und die Wahl eines Eingabefeldes mit dem Cursor oder Tastatur durch Ändern des Aussehen reagiert. :hover und :focus triggern auch einfache Animationen durch CSS transition.