Wie wir in unserem vollständigen Leitfaden bemerkt haben, können Sie <a href=""> Links um beliebige HTML-Blöcke legen. Nennen wir das einen „Block-Link“. So wie Sie einen ganzen „Card“-Inhalt verlinken möchten, weil er ein großes klickbares Ziel darstellt.
<a href="/article/"> <!-- display: block; -->
<div class="card">
<h2>Card</h2>
<img src="..." alt="...">
<p>Content</p>
</div>
</a>
Dazu, Adrian Roselli
Das Schlimmste, was man für einen Block-Link tun kann, ist wahrscheinlich, alles in den
<a href>zu packen.
[…] für einen Screenreader-Benutzer wird die gesamte Zeichenkette vorgelesen, wenn durch die Steuerelemente getappt wird. Im folgenden Beispiel enthält der erste Link die Überschrift, das Bild (ohne es als Bild zu deklarieren) und einen Textblock, der etwa 25 Sekunden zum Vorlesen benötigt, bevor er als Link angekündigt wird. Beim Tippen weiß man nicht immer den Steuerelementtyp, bis der zugängliche Name vollständig ist.
(Das Beispiel ist eine ziemlich normal aussehende Karte mit einer Überschrift, einem Bild und einem Absatz.)
Tun Sie das also nicht.
Die Alternative ist, den Link „normal“ zu lassen, wie nur die Überschrift.
<div class="card">
<h2><a href="/article/">Article</a></h2>
<img src="..." alt="...">
<p>Content</p>
</div>
Die Erweiterung des „klickbaren Bereichs“ des Links, um den gesamten Bereich abzudecken.
.card {
position: relative;
}
.card h2 a::after {
content: "";
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
Das funktioniert für den klickbaren Bereich und löst die Beeinträchtigung für Screenreader-Benutzer.
Aber es gibt noch ein weiteres Problem, das beide Lösungen beeinträchtigt, und das ist die **Textauswahl**. Sie können nicht einfach Ihren Cursor irgendwo in die Karte setzen und Text normal auswählen. Der Klick aktiviert den Link und wartet darauf, dass Sie mouseup ausführen, solange Sie sich noch über dem Link befinden, um ihn auszulösen. Sie erhalten nicht die Möglichkeit, innere Textteile auszuwählen, wie Sie es wahrscheinlich erwarten würden. Es verhindert die Textauswahl überhaupt nicht, macht sie aber umständlich und ärgerlich.
Ich bin mir nicht sicher, ob das leicht zu lösen ist. Vielleicht gibt es eine exotische JavaScript-Lösung, die erkennen kann, ob Sie mit der Textauswahl begonnen haben, und dann keinen Klick auslöst, aber wenn Sie klicken, ohne zu ziehen, dann geht es zum Link. Etwas daran ist für mich jedoch verdächtig.
Update: Schauen Sie sich Heydons „The redundant click event“ section in seinem Artikel über Cards an.
Alles in allem würde ich sagen, dass Block-Links einfach eine schlechte Idee sind. Aber ich würde mich gerne eines Besseren belehren lassen und eine wirklich gute Implementierung sehen, die all diese Probleme löst.
Können wir das Auswahlproblem bei der zweiten Lösung mit `user-select: none` auf dem ::after Pseudo-Element lösen? Werde das morgen ausprobieren.
Den gesamten Block klickbar machen, aber nicht in den Link einbeziehen?
Nach allem, was ich gelesen habe, glaube ich, dass Screenreader dies nicht erkennen. Aber vielleicht verstehe ich das völlig falsch?
Habe gerade `user-select:none` ausprobiert, hat nichts gebracht, da es immer noch Pointer-Events abfängt.
Das ist das, was ich mit meiner bisherigen Herangehensweise erreicht habe: https://codepen.io/dougwollison/pen/poJagLJ
Grundsätzlich durch Schichten des Pseudo-Elements hinter allem anderen ist der Text auswählbar, während jeder andere Teil der Karte den Klick auslöst, aber alle dekorativen Elemente wie Ränder, Icons in Textelementen (die nicht richtig z-indiziert sind) und insbesondere jeglicher Abstand auf Textelementen bedecken klickbaren Platz.
Ehrlich gesagt, angesichts der Inkonsistenz, die dies für einen Benutzer bei Bereichen, die sich leer anfühlen (z. B. Ecken von Textelementen ohne Text), darstellen kann, schadet es wahrscheinlich mehr als es nützt.
Dann sind Sie wieder am Anfang, und die Karte ist nicht klickbar.
Funktioniert nicht, da das Pseudo-Element über allem liegt. Die `user-select`-Eigenschaft steuert nur die Textauswahl. Wenn etwas „über“ dem Text liegt, kann man es sowieso nicht auswählen :(
Könnte sich der `z-index` beim ::after beim Hovern über die Karte ändern?
Man kann, aber wenn man seinen Text mit `z-index` erzwingt, kann man ihn nicht „anklicken“. Man kann ihn nur auswählen. Wir wollen, dass die gesamte Karte klickbar und der gesamte Inhalt auswählbar ist :(
Könnten Sie mit
aria-labelledbyundaria-describedbyein verlinkbares Element erstellen, das schnell als Überschrift bezeichnet wird und dann eine zusätzliche Beschreibung durch den Absatz erhält?Durch Hinzufügen von
draggable="false"zuma-Tag wird der Text in Firefox auswählbar (was das Ziehen von Links ermöglicht, wodurch der Text innerhalb einesanicht mehr auswählbar ist)Codepen-Beispiel hier: https://codepen.io/mikeybinns/pen/LYVQEyz?editors=1100
Mikey, ich habe unten einen Kommentar, der das Risiko der Verwendung von ARIA hier diskutiert. Im Wesentlichen wird der tatsächliche Linktext überschrieben, der Rest des Inhalts verschleiert und die Semantik gestrippt. Verlassen Sie sich wahrscheinlich nicht auf
aria-labelledbyundaria-describedbyhier.Block umschließt Inline aus hierarchischen Gründen. Inline sollte nicht Block umschließen. CSS hat es möglich gemacht, ein A-Link als `display:block` anzuzeigen, sodass es nicht mehr viel Bedarf gibt, die Hierarchie zu brechen.
Dies ermöglicht es dem Benutzer, überall auf der Karte zu klicken, um die URL aufzurufen, und erlaubt ihm gleichzeitig, Text auszuwählen
Linktext ist nicht auswählbar (außer durch Region-Auswahl von außerhalb des Links), aber die Verwendung von „Mehr lesen“, Ellipsen oder sogar einem unsichtbaren Link würde immer noch funktionieren.
Ist es sündhaft, vorzuschlagen, dass Screenreader verbessert werden könnten? Und in Bezug auf die Textauswahl ist das ein seit langem bestehendes Problem auch für „normale“ Links, und es wird, wie Sie beschrieben haben, für Block-Links verschärft. Ich wünsche mir weiterhin heimlich, dass Browser eine Lösung mit gedrückter Alt-Taste erlauben, um Links zu deaktivieren, während ich Text auswähle.
Ich bin mir nicht sicher, ob ich zustimme, dass Block-Links eine schlechte Idee sind. Obwohl das Problem mit der Textauswahl in der Tat nicht ideal ist, wenn man „normale“ Webnutzer beim Navigieren einer Website (insbesondere auf dem Handy) beobachtet, erwarten die Leute Block-Links oder zumindest, dass sie auf das Bild, den Titel, die Beschreibung und alles dazugehörige in der Nähe klicken können.
Die Anzahl der Leute, die Text aus einem Block-Link auswählen, dürfte ziemlich gering sein, ich erinnere mich nicht, dass ich das jemals getan habe. Vergleichen Sie das mit der Benutzererfahrung von Leuten, die auf ein Linkbild klicken und auf das Laden der Seite warten, obwohl dies nicht der Fall ist, weil sie auf die Überschrift klicken mussten – oder die Barrierefreiheit-Beeinträchtigung, dass jedes Element individuell ein Link ist.
So behandle ich „Block-Links“ normalerweise: https://codepen.io/Manoz/pen/NWqybdN
Ich verwende ein Link-Tag und style die Pseudo-Elemente so, wie Sie es in diesem Artikel tun.
Das Einzige, was sich ändert, ist, wenn ich möchte, dass bestimmte Elemente klickbar sind (Tags zum Beispiel), dann spiele ich mit dem `z-index` darauf.
Aber immer noch am „Textauswahl“-Problem hängen geblieben.
http://inclusive-components.design/cards/
Ähnlicher Beitrag, mehr Antworten
Ich mag, wie Heydon das Textauswahlproblem mit JavaScript angeht.
Mit der „redundanten Klick-Event“-Lösung stehe ich vor dem Problem, dass die URL beim Hovern nicht angezeigt wird.
Das ist etwas, an das ich mich als Benutzer gewöhnt habe, um zu sehen, wohin der Link führt.
Gibt es eine Idee, wie man das umgehen könnte?
Das Problem hat man nicht, wenn man den Pseudo-Elementen-Ansatz verwendet, aber dann kann man – wieder einmal – keinen Text auswählen.
Ich habe das kürzlich entdeckt und war super begeistert von dem „redundanten Klick-Event“. Erst als ein Kollege es implementierte, merkte ich, dass dies den Benutzern nicht mehr erlaubt, den Link in einem neuen Tab zu öffnen. Fühlte sich super seltsam an. Wir haben es wieder verworfen und noch nichts Besseres gefunden.
Das kam in unseren A11y-Tests oft auf. Wir haben es gelöst, indem wir ein `data-href`-Attribut und einen Click-Handler zum Container hinzugefügt haben. Wir lassen Klicks innerhalb des Containers nach oben blubbern, es sei denn, sie befinden sich auf tatsächlichen
<a>-Elementen. Dies behandelt klickbare Vorschaubilder als Verbesserung und vermeidet A11y-Probleme mit doppelten Links. Sie können die Navigation abbrechen, wenn der Benutzer Text auswählt, indem Sie prüfen, ob `window.getSelection().type === "Range"`. Bisher scheint es ziemlich gut zu funktionieren!Lustig, dass ich genau dieses Setup gestern gebaut habe und dachte, ich sollte das wirklich nicht tun. Jetzt fühle ich mich schlecht und werde es reparieren gehen!
Ich habe gerade kein Beispiel zur Hand und mache das schon lange nicht mehr auf diese Weise, aber ich glaube, wenn man einen Click-Event an das „.card“ anhängt, das das darin findet und dann den Link öffnet, kann man trotzdem den Text auswählen.
So etwas, wenn Sie jQuery verfügbar haben
(Mobile Geräte müssen wirklich eine „Code“-Tastatur hinzufügen, die gerade Anführungszeichen anstelle von geschweiften verwendet! Ich werde jetzt keine Zeit aufwenden, diese zu korrigieren…)
Da diese Funktionalität wirklich nur ein Komfort für den Benutzer ist, ist es in Ordnung, dass sie aufgrund von JS-Fehlern oder deaktiviertem JS möglicherweise nicht funktioniert. Es gibt immer noch ein klickbares Element.
Aber die Dinge haben sich vielleicht geändert, wie gesagt, es ist schon eine Weile her, und Touch-Events haben die Funktionsweise dieser Teile seitdem, als ich das zuletzt gemacht habe, stark verändert.
Die Textauswahl ist in vielen Anwendungsfällen dieser Struktur wahrscheinlich ein geringfügiges Problem, diese sind wahrscheinlich Navigationselemente, und ein vollständigerer Text (also eine bessere Quelle zum Kopieren) ist wahrscheinlich sowieso nach dem Klicken auf den Link verfügbar?
Ich werde wahrscheinlich einfach die zweite Option wählen – jemand hat letztes Jahr eine Beschreibung dieses Musters geschrieben und es, glaube ich, als „Breakout Button“ bezeichnet, weil er den klickbaren Bereich aus seiner normalen Position herausspringt. Einfacher, kein JavaScript, vollständig zugänglich.
https://developer.mozilla.org/en-US/docs/Web/CSS/user-select
`user-select` vielleicht etwas??
Würden
role="presentation"oderaria-hiddenauf einem dieser Elemente funktionieren? Alter Post von timwright.org: „…role="presentation"wird keine Inhalte oder semantische Definition von fokussierbaren Elementen entfernen. Das bedeutet, Ihre Links, Schaltflächen und Eingaben bleiben so, wie sie sein sollten, zusammen mit allen Inhalten…“Könnte das mit
aria-labelledbyundaria-describedbygelöst werden? Oder übersehe ich etwas? Beispiel: https://codepen.io/falldowngoboone/pen/LYVdvQx.Ich bin wirklich neugierig darauf, weil ich einen Vortrag über zugängliche Muster vorbereite.
Sieht nach einer guten Idee für die Beschriftung aus, hilft aber nicht viel bei der Textauswahl.
Ich habe den CodePen aktualisiert, um dies widerzuspiegeln. Sehr informativ. Danke!
Ryan, das Problem hierbei ist, dass `aria-labeledby` den gesamten Inhalt des Links überschreibt. Das Hinzufügen von `aria-describedby` mildert dies nur ein wenig ab, da es erst nach einer Pause angesagt wird. Ein Screenreader-Benutzer wartet oft nicht und verpasst diesen zusätzlichen Kontext beim Tippen durch die Seite.
Beide Attribute ignorieren auch jede Semantik, wenn der Wert für Benutzer angesagt wird. Wenn Ihre Karte eine Liste, eine Unterüberschrift oder andere Inhalte mit Struktur oder Semantik enthält, werden diese Informationen nicht übermittelt.
Beachten Sie, dass einige Screenreader-Benutzer mit den Pfeiltasten durch die Links navigieren und davon nicht blockiert werden. Ich spreche darüber und einige andere Herausforderungen in Antworten auf ARIA-bezogene Fragen auf meinem Beitrag.