HTML/Tutorials/Links/Maus- und Tastaturinteraktionen
Verweise (engl. Hyperlinks oder kurz Links) sollen nicht nur gelesen, sondern auch gezielt angesteuert und ausgeführt werden können. Damit für Benutzer jederzeit erkennbar bleibt, in welchem Zustand sich ein Link gerade befindet, stellt CSS dynamische Pseudoklassen zur Verfügung. Sie helfen dabei, unterschiedliche Interaktionen wie „aktiv“, „besucht“ oder „fokussiert“ visuell sichtbar zu machen.
In diesem Kapitel lernst du, wie du Links für Maus- und Tastaturinteraktionen richtig gestaltest und dadurch sowohl die Bedienbarkeit als auch die Barrierefreiheit deiner Webseite verbesserst. Dabei untersuchen wir genauer, wie man mit CSS-Selektoren umgeht.
Inhaltsverzeichnis
hover, active und focus
Wenn man mit der Maus über einen Link fährt, ihn anklickt oder sich mit der Tabulator-Taste (↹) durch die Links einer Seite bewegt, verändert sich das Erscheinungsbild der Links. Dadurch wird für den Nutzer sichtbar, ob ein Link bereits besucht wurde, aktuell ausgewählt ist oder gerade mit der Maus berührt wird.
Diese CSS-Selektoren nennen sich dynamische Pseudoklassen und sprechen auf unmittelbare Interaktion des Benutzers an. Folgende Pseudoklassen sind wichtig:
- :hover, wenn Elemente mit dem Mauszeiger berührt werden (
:hover
; englisch to hover: schweben), - :active, wenn sie aktuell angeklickt sind, und
- :focus, wenn sie zum Beispiel durch die Tabulatortaste ↹ angewählt wurden.
a:focus { background-color: red; color: black;}
a:hover { background-color: blue; color: white; }
a:active { background-color: yellow; color: black; }
<ul>
<li><a href="https://wiki.selfhtml.org">SELFHTML</a></li>
<li><a href="https://forum.selfhtml.org">Forum</a></li>
<li><a href="https://blog.selfhtml.org">Blog</a></li>
</ul>
Link-Elemente, die mit der Tabulatortaste ↹ ausgewählt werden, erhalten einen roten Hintergrund, werden sie mit dem Mauszeiger berührt, wechselt der Hintergrund zu blau, während die Links angeklickt sind, ist ihre Hintergrundfarbe gelb.
:focus
zuvor notierte Eigenschaften für :hover
, sodass ein mit der Tabulator-Taste ausgewähltes Element scheinbar nicht auf :hover
reagiert.Nur der Vollständigkeit halben erwähnen wir …
- :visited für besuchte Links (Eher verwirrend - früher auch für History Stealing missbraucht; SELFHTML verzichtet auf eine solche Kennzeichnung.)
- :link für unbesuchte Links (Der Name suggeriert zwar, dass alle Links selektiert würden, dass stimmt aber nicht.)
- :any-link für alle Links (a und area) - einfacher wäre
a
oder[href]
.
focus vs focus-visible
Wenn man auf einen Link oder ein Eingabefeld klickt, erhält dieses Element den Fokus. Das bedeutet, dass es nun Eingaben entgegennehmen oder Aktionen auslösen kann. Ein fokussiertes Element wird standardmäßig durch einen blauen Fokusring hervorgehoben. Dieser Fokusring besteht technisch aus einer outline.
Früher wurde die standardmäßige outline oft per CSS entfernt, um ein „schöneres“ Erscheinungsbild zu erzielen. Für Tastaturnutzer bedeutete das jedoch, dass fokussierte Elemente nicht mehr erkennbar waren. Um dieses Problem zu lösen, haben Browser-Hersteller den Pseudoklassen-Selektor :focus-visible eingeführt. Damit lässt sich gezielt steuern, wann ein sichtbarer Fokusring angezeigt wird – zum Beispiel nur dann, wenn ein Element mit der Tastatur fokussiert wurde, nicht aber beim Klick mit der Maus.
a:focus {
outline: none; /* default focus outline wird entfernt */
}
a:focus-visible {
outline: 2px solid blue; /* custom focus für Tastaturnutzer */
outline-offset: 4px;
border-radius: 4px;
}
Fallstrick: Hovereffekt
Die Möglichkeiten von CSS sind gleichzeitig auch sein Fluch! Viele „Designer“ erliegen der Versuchung und normalisieren Links so, dass sie wie gewöhnlicher Text aussehen. Diese Links werden erst bei :hover durch Einblendungen, geänderte Mauszeiger, etc. erkennbar.
Angesichts der immer weiter um sich greifenden Verwendung von Touch-Screens, die keinen :hover
-Zustand kennen, ist die Verwendung dieser Hover-Effekte nicht nur sinnlos, sondern geradezu kontraproduktiv. Trent Walton ruft in seinem Artikel „Non Hover“ zu einer Abkehr vom bisherigen Design mit Hover-Effekten auf.[1]
Zeichne neben :hover auch immer die Pseudoklasse :focus aus. Nicht nur Sehbehinderte - auch viele Profis bedienen Webseiten lieber mit der Tastatur!
Unterstreichungen
Die Unterstreichung kann mit text-decoration verändert oder unterdrückt werden. Mit text-decoration-style und text-decoration-color sind Art und Farbe der Unterstreichung formatierbar.
text-decoration: none;
entfernt oder die Textfarbe an die Farbe des normalen Fließtexts anpasst, verliert man damit ein wichtiges Erkennungsmerkmal von Links.Es gibt aber workarounds, mit denen man einen vergleichbaren Effekt erzielen kann.
a.eins {
text-decoration: none;
border-bottom: .2em dotted blue;
}
a.zwei {
text-decoration: none;
border-bottom: .1em dashed green;
}
a.drei {
text-decoration: none;
border-bottom: .4em double red;
}
In diesem Beispiel wird die Linkkennzeichnung mit text-decoration: none;
entfernt und dafür mit border eine untere Randlinie festgelegt. Sie erhält über border-style und border-color unterschiedliche Zuweisungen.
Alternativ kann man eine Unterstreichung auch mit der box-shadow
-Eigenschaft vornehmen, wie dieses attraktive Beispiel der Link-Kennzeichnung mit animierten Innenschatten zeigt.
a {
color: blue;
box-shadow: inset 0 -3px 0 -1px blue;
padding: .25em 0;
text-decoration: none;
transition: all .5s;
}
a:hover,
a:focus {
box-shadow: inset 0 -30px 0 skyblue;
}
Das Beispiel enthält drei Links. Sie sind durch die blaue Textfarbe und die blaue Unterstreichung mehrfach gekennzeichnet.
Dabei wird die Unterstreichung aber nicht mit text-decoration:underline
realisiert, sondern durch einen scharfen Innenschatten. Wenn das Link-Element den Fokus erhält, wird der Innenschatten über die gesamte Fläche vergößert und wirkt nun nicht mehr als Unterstreichung, sondern als jetzt (hellerer) Hintergrund, da auch die Farbangabe geändert wurde.
Links mit Symbolen kennzeichnen
Man kann Links auch mit Symbolen und kleinen Grafiken kenntlich machen. Da mit UTF-8 Zugriff auf eine Vielzahl von Zeichen besteht (→ Unicode-Tabellen), kann man im Allgemeinen auf das Einbinden von Hintergrundgrafiken verzichten.
a {
display: inline-block;
padding-left: .5em;
text-decoration: none;
}
a::before {
content: '→ ';
}
a.backlink::before {
content: '← ';
}
a.toplink::before {
content: '↑ ';
}
a[rev] {
padding-left: 0;
}
a[rev]::before {
content: '';
}
Allen Links wird ein linker Innenabstand gegeben. Hier wird über ein Pseudoelement ::before mit content: '→ ';
ein Pfeil erzeugt.
Danach werden zwei Klassen festgelegt:
- Die Klasse
toplink
erhält einen Pfeil nach oben, - die Klasse
backlink
einen Linkspfeil.
Fußnoten benötigen keinen Pfeil, also wird hier mit dem Attributsselektor für a[rev]
die Festlegung des linken Rands und des Pseudoelements wieder rückgängig gemacht.
externe und interne Links kennzeichnen
CSS erlaubt auch das Selektieren von Elementen mit bestimmten Attributwerten. Mit a[href^="http"]
kann man beispielsweise alle Links auswählen, die mit http
beginnen (also http://
oder https://
). In der Regel können Sie so interne Links von externen Links unterscheiden.
In früheren Beispielen wurde dies durch die Verwendung mehrerer, verschiedenfarbiger Hintergrundgrafiken erreicht.[2] Allerdings lassen sich solche Grafiken, die auf genau eine Schriftgröße und ein Farbkonzept abgestimmt sind, nachträglich nur schwer ändern.
Sinnvoller ist der Einsatz einer SVG-Grafik, der die passenden Farben für die verschiedenen Zustände einfach zugewiesen werden können. SVGs sind im Gegensatz zu Rastergrafiken responsiv, da sie sich beliebig skalieren lassen und dabei immer scharf bleiben.
Dafür benötigen wir eine SVG-Grafik, die wir als Icon verwenden:
<svg viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
<polygon fill="blue" points="2,2 5,2 5,3 3,3 3,9 9,9 9,7 10,7 10,10 2,10"/>
<polygon points="6.2,2 10,2 10,5.8 8.6,4.4 6.5,6.5 5.5,5.5 7.6,3.4"/>
</svg>
Die SVG-Grafik enthält zwei polygon-Elemente. Dies hat den Vorteil, dass wir im Gegensatz zu einem path-Element nur die Füllfarbe mit fill und keine Kontur festlegen müssen.
<a href="https://wiki.selfhtml.org/.../Beispiel:HTML_a-Element3.html">ein Verweis zu einer anderen Seite</a>
<a href="#zweitens">ein Verweis innerhalb dieser Seite</a>
Mailen Sie uns an: <a href="mailto:jemand@example.com">jemand@example.com</a>
Das Beispiel enthält drei verschiedene Links. Während der erste auf eine andere Seite verweist, stellt der zweite einen internen Anker auf die Überschrift weiter unten dar. Der dritte Link referenziert eine E-Mail-Adresse.
a {
padding-right: 2em;
color: blue;
background: url("data:image/svg+xml,%3Csvg%20viewBox...%20fill%3D%22blue%22%20...") no-repeat right;
}
a:hover,
a:focus {
color: purple;
background: #fffbf0 url("data:image/svg+xml,%3Csvg%20viewBox...%20fill%3D%22purple%22%20") no-repeat right;
}
a[href^="http"] {
background: url("data:image/svg+xml,%3Csvg%20viewBox...") no-repeat right;
}
a[href^="http"]:hover,
a[href^="http"]:focus {
background: #fffbf0 url("data:image/svg+xml,%3Csvg%20viewBox...") no-repeat right;
}
Alle Links erhalten mit padding-right einen rechten Innenabstand, in den dann mit background die URL-kodierte SVG-Grafik dargestellt wird.
Leider kann man bei extern referenzierten Grafiken die Füllfarbe nicht direkt über CSS ändern, sodass die Grafik für die Pseudoklassen :hover
und :focus
leicht abgeändert erneut referenziert werden muss. Anstelle des fill="blue"
wurde die Füllfarbe analog zur Textfarbe des Links auf purple
geändert.
Diese manuelle Änderung ist aber immer noch einfacher als die Farbänderung bei einer Rastergrafik.
Über den Attributwertsselektor a[href^="http"]
werden alle externen Links selektiert und mit einer anderen Grafik versehen.
Es gibt weitere Möglichkeiten, SVGs in einer Seite zu verwenden:
Links auf unterschiedliche Dokumenttypen kennzeichnen
Häufig werden bei verlinkten Dateien unterschiedliche Formate angeboten. Sie können diese Links neben dem erklärenden Linktext aber auch durch allgemein verständliche Icons zusätzlich kennzeichnen.
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.
Ein Entwickler sollte sich immer fragen, ob er den Inhalt des PDFs in normalem HTML notieren kann, damit das CSS auf alle Inhalte der webseite wirken kann.
Im folgenden Beispiel soll von einem Musikstück sowohl die mp3-Version, als auch eine gezippte Variante zum Download angeboten werden.
<ul>
<li>
Europahymne
<a href="Europahymne.mp3" title="mp3 direkt hören!" type="audio/mp3"><span>mp3</span> (976 kB)</a>
<a href="Europahymne.zip" title="mp3 als ZIP-Archiv" type="application/zip"><span>ZIP</span> (925 kB)</a>
</li>
</ul>
Jedes Musikstück wird sowohl als mp3 als auch als zip-Archiv angeboten. Jeder Link muss einen Linktext haben, der bei Downloads auch die Dateigröße angeben sollte.
a[href$=".mp3"] span,
a[href$=".zip"] span {
width: 2.5em;
height: 2.5em;
margin-right: 0.5em;
display: inline-block;
font: 0/0;
color: transparent;
}
a[href$=".mp3"] span {
background-image: url("mp3.svg");
}
a[type="application/zip"] span {
background-image: url("zip.svg");
}
Im Beispiel gibt es drei verschiedene Selektoren für Dateitypen:
- Die Präsenz des Attributs
type
kennzeichnet allgemein einen Link auf einen anderen Dateityp. - mp3-Dateien werden anhand einer Teilübereinstimmung, das heißt der Dateiendung
.mp3
, selektiert. - zip-Archive haben den MIME-Type
application/zip
, der im type-Attribut angegeben ist. Dieser Wert wird selektiert.
Abweichend dazu werden im kompletten Beispiel die SVG-Grafiken mit background-image nicht wie im oberen Beispiel als externe Grafiken, sondern direkt URL-kodiert notiert:
url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20viewBox%...");
Die Breite und Höhe wird in relativen em angegeben, damit die Grafik sich bei einer Änderung der Schriftgröße ebenfalls anpasst.
li > span {
display: inline-block;
width: 15em;
}
li > a {
display: inline-block;
width: 10em;
}
Damit die beiden Icons auch bei unterschiedlich langen Titelnamen tabellenartig untereinander dargestellt werden, erhalten die Titel innerhalb des ersten spans und die Links jeweils eine feste Breite. Damit dies bei Inline-Elementen wirkt, erhalten sie zusätzlich ein display-block;
.
Um in Webseiten produktiv verwendet werden zu können, müsste man die Links, die ja nur „mp3“ oder „zip“ heißen, mit ARIA-Attributen an den Titel im span binden. Im jetzigen Zustand wäre es für Benutzer von Screenreadern nur schwer zu erkennen, welcher Link zu welchem Titel gehört.
Bei einem Klick auf mp3-Dateien öffnet sich im Allgemeinen der Browser-eigene Audio-Player außerhalb der Webseite. Schöner wäre es, wenn die Datei mit einem eigenen audio-Player, der sich in Aussehen und Funktionalität am „look & feel“ der Webseite orientiert, öffnet.
„Cards“ als Alternative zu Textlinks
Textlinks gehen trotz aussagekräftigem Linktext in umfangreicheren Webseiten oft in der Masse unter. Deshalb haben sich in den letzten Jahren Cards als Alternative etabliert:
- Mehr Klickfläche: Statt dass nur ein einzelnes Wort oder Icon anklickbar ist, wird der gesamte „Card“-Block zum Link. Das erleichtert die Bedienung, vor allem auf Touchscreens.
- Bessere Orientierung: Cards können nicht nur Text, sondern auch Bilder, Icons und Zusatzinfos enthalten. Nutzer erkennen sofort, worum es geht.
Cards funktionieren gut in Übersichtsseiten (z. B. Blogartikel, Produktlisten, Tutorials). Nutzer können zwischen mehreren Angeboten vergleichen und haben dieselbe Interaktionsfläche.
Und wie könnte man so etwas realisieren?
Seit HTML5 ist es erlaubt, innerhalb von Verweisen weitere Elemente zu notieren. So kann man ganze Abschnitte und Blöcke verlinken:
<a class="card" href="https://wiki.selfhtml.org/Einstieg in CSS">
<img class="icon" src="CSS_logo.svg" alt="">
<p class="title">Einstieg in CSS</p>
<ul>
<li>Warum Layouts mit CSS?</li>
<li>Webseiten responsiv umbauen</li>
<li>Stylesheets für HTML und SVG</li>
</ul>
</a>
Erlaubt heißt aber nicht, dass man das so tun sollte. Ein Screenreader würde in dem Fall den gesamten Text Einstieg in CSS, Warum Layouts mit CSS?, Webseiten responsiv umbauen, Stylesheets für HTML und SVG als Linktxt vorlesen, was Nutzern die Navigation auf der Seite erschwert.
Könnte man den Link nicht in der Card lassen?
Elternelemente selektieren mit focus-within
Im Selektoren-Tutorial wurde gezeigt, dass man weder Eltern- noch vorhergehende Elemente selektieren kann, der Geschwister-Kombinator zielt auf nachfolgende Elemente.
Mit focus-within wird es jetzt doch wahr: Eltern- und andere Vorfahren-Elemente werden selektiert, wenn eines der Kinder den Fokus besitzt.
Auf den Übersichtsseiten des Wiki gibt es Cards, die neben dem – aussagekräftigen – Linktext noch ein Icon und weitere Erklärungen (neudeutsch: Teaser) zur Verfügung stellen:
.card a:focus {
outline: none;
}
.card:hover,
.card:focus-within {
border-color: skyblue;
box-shadow: 0 8px 16px rgb(51 117 153 / 0.6);
}
Im ersten Regelsatz wird der Fokusring für alle Links in den Cards ausgeschaltet.
Im zweiten Regelsatz wird eine Card, deren Link (als Kind-Element) den Fokus hat, visuell gehighlighted und der Link kann dann mit Enter ↵ getriggert werden.
.card:hover
lässt die Card ebenfalls aktiviert erscheinen, ein Klick außerhalb des Links löst jedoch nichts aus. Deshalb wäre es zu erwägen, wie im oberen Beispiel das a-Element um Linktext, Icons und Teasertext zu legen.
Klickbare Fläche durch Pseudoelement vergrößern
Ich habe mich dafür entschieden, die klickbare Fläche mit absolut positioniertem a::after-Pseudoelement auf die Größe der Card auszudehnen.[3]
.card {
position: relative;
}
.card a::before {
content: "";
position: absolute;
inset: 0;
z-index: 1;
}
Dafür erhält die Card ein position: relative
. Sie wird damit zum Bezugspunkt für das absolut positionierte Pseudoelement ohne Inhalt. Es wird mit inset, der zusammenfassenden Eigenschaft für top, left, right und bottom auf die Größe des Großelternelements ausgedehnt.
Der Nachteil ist: Da sich der Text hinter dem Pseudoelement befindet, kann er nicht markiert und kopiert werden.
Dies kann aber auch dynamisch mit JavaScript erfolgen:
const boxes = document.querySelectorAll('.card');
boxes.forEach(box => {
box.classList.add('js-enabled');
const readMoreLink = box.querySelector('a');
box.addEventListener('click', event => {
if (event.target !== readMoreLink)
{
readMoreLink.click();
}
});
});
Siehe auch
- Navigation
- Dropdown-Menüs
- Flyout-Menü
- responsive Imagemaps
Klickflächen innerhalb eines Bilds? -
Das wird jetzt mit SVG gemacht!
Quellen
- ↑ Trent Walton: Non Hover
- ↑ apsel-mv.de: Externe und interne Verweise durch Grafiken kennzeichnen
- ↑ SELF-Forum: Default Properies? von Gunnar Bittersmann am 27.02.2018
Siehe: CodePen Linked Boxes