Barrierefreie Alerts leicht gemacht mit der Popover API
Benachrichtigungen (Alerts) sind ein gängiges Element auf Websites. Sie lenken die Aufmerksamkeit der Nutzer:innen auf eine wichtige Nachricht, ohne den aktuellen Workflow zu unterbrechen. Zum Beispiel: „Artikel wurde dem Warenkorb hinzugefügt“ oder „Login ist fehlgeschlagen: Prüfen Sie Benutzernamen/Kennwort“.
Dank der neuen Popover API und der neuen Möglichkeiten von CSS-Animationen wird es bald viel einfacher werden, barrierefreie und schön animierte Alerts zu erstellen. Ich habe eine Demo vorbereitet, die ihr ausprobieren könnt.
Foto: © Thirdman / pexels.com
Falls ihr mit der Popover API noch nicht vertraut seid, solltet ihr zuerst meinen Artikel „Einfach herausragend! Die neue Popover API und CSS Anchor Positioning“ lesen. Ich werde hier die Grundlagen nicht wiederholen und mich stattdessen auf den speziellen Anwendungsfall konzentrieren.
Barrierefreie Alerts Demo
Hier ist meine Demo für barrierefreie Alerts mit der Popover API. Ihr könnt sowohl die Nachricht als auch die Dauer und Position der Meldung anpassen. Probiert es aus:
Das Alert erscheint über allen anderen Elementen der Seite und wird von Screenreadern automatisch vorgelesen. Ich habe dieses Verhalten mit JAWS, NVDA, TalkBack und VoiceOver. getestet. Die aktuelle Tätigkeit des Nutzers wird nicht unterbrochen und das Alert verschwindet nach einiger Zeit.
Details der Implementierung
Schauen wir uns nun die verschiedenen Bausteine an, mit denen ich die barrierefreien, animierten Alerts gestaltet habe.
Dynamisches HTML erzeugen
Ich habe einen Angular-Service implementiert, der das Popover-Element
mit JavaScript-Methoden wie createElement()
und appendChild()
dynamisch
erzeugt. Im Demo-Code
findet ihr weitere Details. Ihr müsst nicht mit dem Angular-Framework vertraut sein, um das Wichtigste zu verstehen.
Der folgende HTML-Code wird einem Container am Ende des body-Elements hinzugefügt:
<div popover="manual" role="alert" class="alert top-right">
This is a very important message
</div>
Das popover
-Attribut verwandelt das div
-Element in ein Popover, das
zunächst vom Browser ausgeblendet wird. Wir zeigen das Popover-Alert an, indem wir die Methode
showPopover() des Elements aufrufen.
Mittels popover="manual"
definieren wir einen manuellen Popover-Status für das Element. Damit
verhindern wir Light-Dismiss, also das automatische Schließen des Popovers, wenn Nutzer:innen mit anderen Elementen auf der
Seite interagieren. Stattdessen schließen wir das Popover programmatisch mit der Methode
hidePopover().
Semantisches Markup
Setzt role="alert"
auf das Popover-Element, um es als Alert zu definieren. Das Dokument
Accessible Rich Internet Applications (WAI-ARIA) 1.2
beschreibt die Alert-Rolle wie folgt:
A type of live region with important, and usually time-sensitive, information. [...] Alerts are assertive live regions, which means they cause immediate notification for assistive technology users.
Im Allgemeinen verwenden wir ARIA-Live-Regionen,
um dynamische Inhaltsänderungen zu kommunizieren. Das Setzen von role="alert"
hat denselben Effekt wie
das Setzen von aria-live="assertive"
und aria-atomic="true"
. Das heißt,
Screenreader lesen die Nachricht des Alerts sofort vor, sobald das Popover angezeigt wird.
Animation
Jetzt machen wir noch den visuellen Feinschliff und fügen dem Popover-Element eine Animation hinzu. Es gibt aber ein Problem:
Popover werden anfangs durch display: none
ausgeblendet. Was für ein Albtraum! Das erzeugt gleich
zwei Hindernisse:
- Ein Element mit dem Wert
none
für diedisplay
-Eigenschaft wird nicht gerendert. Daher hat es keine berechneten Werte für die verschiedenen CSS-Eigenschaften wie z.B.opacity
. Wenn es keinen berechneten Wert gibt, haben wir keinen Ausgangspunkt für dietransition
. - Das gleiche Problem besteht auch in umgekehrter Richtung: Wenn die Eigenschaft
display
aufnone
gesetzt wird, wird das Element sofort aus dem gerenderten HTML-Dokument entfernt, ohne dass dertransition
-Effekt ausgelöst wird.
Glücklicherweise bietet die CSS Transitions Level 2 Spezifikation neue
Möglichkeiten für CSS-Übergänge. Sie definiert die neue @starting-style
Regel:
The @starting-style rule is a grouping rule. The style rules inside it are used to establish styles to transition from, if the previous style change event did not establish a before-change style for the element whose styles are being computed.
So können wir einen Ausgangszustand für den Übergang definieren, wenn sich der Anzeigetyp von none
zu einem anderen Typ ändert.
Der zweite Puzzlestein ist die neue transition-behavior
-Eigenschaft und ihr
Wert allow-discrete
:
The transition-behavior property specifies whether transitions will be started or not for discrete properties.
Diskrete Eigenschaften haben Werte, die nicht interpoliert werden können. Dies ist z.B. bei den Eigenschaften
display und overlay
der Fall. Um Übergänge für sie zuzulassen, müssen wir den Wert allow-discrete
definieren.
Ihr könnt den Wert für transition-behavior
auch als Teil einer Shorthand-Deklaration angeben.
Wie passt das nun alles zusammen? Meine Demo enthält die Position "top-right", bei der das Alert langsam sichtbar wird und von rechts in den sichtbaren Bereich rutscht. Hier ist der CSS-Code für den Übergang:
.alert[popover].top-right {
/* Final state of the exit animation */
opacity: 0;
transform: translateX(100%);
transition: opacity 0.5s,
transform 0.5s,
overlay 0.5s allow-discrete,
display 0.5s allow-discrete;
}
.alert[popover].top-right:popover-open {
/* Final state of the show animation */
opacity: 1;
transform: translateX(0);
}
/* Needs to be after the previous [popover]:popover-open rule to take effect, as the specificity is the same */
@starting-style {
.alert[popover].top-right:popover-open {
opacity: 0;
transform: translateX(100%);
}
}
Im obigen Beispiel werden die Eigenschaften opacity
und transform
für
die Dauer einer halben Sekunde animiert. Wir möchten, dass der Browser den animierten Inhalt anzeigt und das Popover im
Top Layer bleibt, solange die Animation läuft. Um dies zu
erreichen, definieren wir auch overlay 0.5s allow-discrete
und display 0.5s allow-discrete
.
Achtung! Diese Funktionen sind experimentell und können sich in Zukunft ändern!
Browser-Unterstützung
Das popover
-Attribut wird bereits von allen wichtigen Browsern unterstützt.
Zum Zeitpunkt der Erstellung dieses Artikels hatte Firefox die Funktion nur in seinen experimentellen Nightly-Builds aktiviert.
Ich erwarte aber, dass Firefox die Funktion bald releast.
Die neuen Funktionen für transition
werden derzeit nur von
Chrome und Edge unterstützt. Ich hoffe, dass sie Teil der
Interop 2024 sein werden und bis Ende des Jahres eine
browserübergreifende Kompatibilität erreichen.
Nützliche Links
Erstellt am