Ein CSS für Trap Focus Innerhalb eines Elements

0
52

Vor kurzem Las ich diesen Artikel von Keith Grant eingeführt, die die neu angekommenen <dialog>. Begeistert von dieser neuen UI-element, sofort setzte ich mich zu Experimentieren, um zu sehen, wie es effektiv genutzt werden kann als modal — die häufigste Verwendung. Beim Experimentieren entdeckte ich eine saubere CSS-trick, wie trap Fokus innerhalb des <dialog> – element, eine Allgemeine Zugänglichkeit Voraussetzung für modals, und ein notorisch schwierig.

Was ist Fokus-trapping?

Zunächst ein Zitat aus der W3C-Dokumentation über das, was passieren soll folgende ein-Taste drücken Sie innerhalb des dialogs:

Tab:

  • Bewegt den Fokus zum nächsten tab-Lage-element im dialog.
  • Wenn der Fokus auf der letzten tab-fähig element in das Dialogfeld, wird der Fokus auf die erste Registerkarte-Lage-element im dialog.

Umschalt + Tab

  • Bewegt den Fokus zum vorigen tab-Lage-element im dialog.
  • Wenn der Fokus auf der ersten Registerkarte können-element in das Dialogfeld, wird der Fokus auf die Letzte Registerkarte-Lage-element im dialog.

Um zusammenzufassen, wenn Sie innerhalb des dialogs drücken Sie Tab oder Umschalt+Tab sollte einen Zyklus der Fokus innerhalb des dialogs nur unter der fokussierbare Elemente in das Dialogfeld.

Dies macht Sinn, denn wenn ein dialog geöffnet ist, wird eine Benutzer-Interaktion ist nur drin, damit der Fokus auf Flucht außerhalb des Dialogfensters im Grunde mischen Kontexten und möglicherweise erstellen Sie ein Zustand, wo der Benutzer nicht weiß, welches element den Fokus hat.

Also, gehen wir zurück zu der Idee des modal, unsere Erwartung wäre, dass die Navigation mit der Tabulatortaste innerhalb der modalen würde sich nur auf Elemente innerhalb des modalen. Alles, was außerhalb des Kontexts der modalen wäre aus dem Rahmen, weil Sie die Registerkarte ist nur im Zusammenhang mit dem, was in ihm ist. Dies ist, was wir damit meinen Fokus trapping.

Eine Umsetzung mit JavaScript

Wenn wir setzen, konzentrieren trapping in ein <dialog>, der häufigste Ansatz wäre Folgendes zu tun, wenn das Dialogfeld geöffnet wird:

1. Greifen Sie alle justierbares/antipp-Elemente im dialog.
2. Hören Sie Tab und Umschalt+Tab drücken von Tasten und manuell Fokus des nächsten oder vorherigen Elements, respectively.
3. Wenn der Tastendruck geschieht, auf das erste fokussierbare element, dann Schwerpunkt die Letzte fokussierbare element in der Kette ist und Umgekehrt.

Auf diese Weise erzeugen wir eine Schleife im Fokus, wie der Benutzer die Taste Tab oder Shift+Tab. Sehen Sie diese W3C-code-snippet als ein Beispiel von, wie diese möglicherweise angegangen werden, mit JavaScript. Du wirst sehen, es ist schon ein bisschen JavaScript.

Geben Sie :konzentrieren Sie sich-innerhalb

Zurück zu meinem experiment mit dem neuen <dialog> – element. Wenn Sie sich Gedanken über die ” focus-trapping, eine CSS-pseudo-Klasse (auch sehr aktuelle in-Browser) sofort kam mir in den Sinn : :focus-in.

Wenn Sie haben nicht gehört, dass vor, es ist ein element, das den Fokus erhalten oder enthält ein element, das den Fokus erhalten hätte. So, zum Beispiel, Sie haben ein <div> und darin ist ein input-element. Wenn Sie möchten, um Stil, <div>, wenn die enthaltenen input-Fokus hat, kann Sie es ja gerne machen:

div:focus-innerhalb {
border: 2px solid red;
}

Siehe Stift :focus-innerhalb von Geoff Graham (@geoffgraham) auf CodePen.

Der CSS-trick zu Fokus trapping

Lassen Sie uns nutzen :konzentrieren Sie sich-innerhalb und CSS-übergänge zu implementieren, die eine grundlegende Fokus-Falle innerhalb von ein <dialog> – element.

Um zusammenzufassen, ist hier, wie der trick funktioniert. Wenn der Fokus nicht innerhalb des dialogs (und der dialog offen ist), haben wir:

  1. auslösen einer CSS-transition
  2. zu erkennen, dass die ” Fertigstellung der überblendung in JavaScript
  3. Fokus das erste element im dialog

Aber, lassen Sie uns zuerst einrichten. Hier ist der basic-dialog und öffnen Funktionalität:

<button id=”button”>dialog Öffnen</button>
<dialog id=”modal”>
<form action=””>
<label>
<input type=”text” /> Username
</label>
<label>
<input type=”password” /> Passwort
</label>
<input type=”submit” value=”Absenden” />
</form>
</dialog>
– Taste.onclick = () => {
modal.showModal();
}

Dort gehen wir. Klicken Sie auf die Schaltfläche öffnen sollten, unser dialog. Nur so viel code erforderlich ist, um eine wesentliche Arbeits-modal mit dem neuen <dialog> – element!

Finden Sie den Stift Einfach <dialog&rt; von Geoff Graham (@geoffgraham) auf CodePen.

Wenn Sie eröffnet den dialog im obigen Beispiel und begann, Navigation mit der Tabulatortaste mehrmals, Sie haben vielleicht schon bemerkt, das problem: der focus beginnt mit der Elemente in den dialog, aber dann verlässt, sobald das Letzte element in dem dialog übergeben wurde.

Dies ist der Kern unserer trick. Wir irgendwie senden müssen, die den Fokus verloren erkannt mit :focus-in über JavaScript, so dass wir senden können, den Fokus wieder auf den dialog. Dies ist, wo die CSS-übergänge ins Spiel kommen. Eine CSS-übergang ist etwas, das geschieht über CSS, aber strahlt Ereignisse in JavaScript zu. In unserem Fall, wir können das auslösen einer transition auf jede Eigenschaft mit einer vernachlässigbar (da ist es egal, in unserem Fall) optische Unterschied und achten Sie auf die “Fertigstellung der überblendung” in JavaScript.

Beachten Sie, dass wir auslösen müssen diesen übergang, wenn das Dialogfeld geöffnet ist, aber nicht den Fokus haben, drin.

dialog {
background-color: rgb(255, 255, 255);
}
Dialogfeld[öffnen]:not(:focus-in) {
background-color: rgb(255, 255, 254);
transition: background-color 0,01 s;
}

Sehen wir nach, was CSS tut.

  1. Wir setzen eine hintergrund-Farbe unserer Wahl auf den dialog. Dies ist nicht notwendig, stellt aber sicher, wir haben die gleiche Hintergrundfarbe in allen Browsern.
  2. Das Dialogfeld[öffnen]:not(:focus-in) – Selektor gilt, wenn der dialog geöffnet ist, aber nicht Fokus auf oder in es. Dies funktioniert, da die native <dialog> – element stellt eine open-Attribut, wenn es geöffnet ist.
  3. Innerhalb dieser Regel, wir ändern die hintergrund-Farbe, indem Sie einen Mindestbetrag. Dies ist die mindestens erforderliche änderung auslösen einer CSS-animation und zur gleichen Zeit nicht verursacht optische Unterschied für den Benutzer (denken Sie daran, dies ist eine dummy-transition). Auch setzen wir in der transition-Eigenschaft mit einer sehr kleinen Dauer, denn wir wollen es bis zum Ende so bald wie möglich zu erhalten und erkannt, in JavaScript.

Ein Hauch von JavaScript

Nun, alles, was wir tun müssen, ist zu erkennen, das Ende unserer ausgelöst CSS-übergang und der Fokus wieder das erste element innerhalb des modal, etwa so:

modal.addEventListener(‘transitionend’, (e) => {
modal.querySelector(‘input’).focus();
});

Wir legen ein transitionend-listener auf den modal und innerhalb der callback, den wir den Fokus im ersten Eingaben innerhalb der modal. Fertig!

Finden Sie die Pen-Dialog konzentrieren trapping mit CSS Kushagra Gour (@chinchang) auf CodePen.

Einschränkungen

Dies ist eine schnelle experiment, das ich Tat, um ein funktionierender proof-of-concept der Fokus trapping mit dem :focus-in-pseudo-Klasse. Es hat einige Einschränkungen im Vergleich zu dedizierten JavaScript-Lösungen, dies zu erreichen. Trotzdem, etwas ist besser als nichts!

Hier sind ein paar Dinge, die diese Umsetzung fehlt:

  1. Nach W3C Richtlinien, sollte der Fokus Zyklus auf das fokussierbare element. Aber wir sind immer mit dem Fokus auf das erste input-element. Dies ist, weil ohne das schreiben mehr JavaScript, können wir nicht wissen, ob der Fokus verloren war vom ersten oder letzten element.
  2. Wir sind immer mit dem Fokus zurück auf das erste input-element. Aber es gibt viele weitere fokussierbare HTML-Elemente, die vorhanden sein könnten, bevor die Eingabe-oder vielleicht es ist nicht input-element innerhalb des modalen. Wieder, vollwertige JavaScript-Lösungen zu erkennen und zu pflegen eine Liste aller fokussierbare Elemente und konzentrieren die richtige.

Besser (JavaScript -) Implementierungen von focus-trapping

  1. Wie bereits erwähnt, ein lauffähiges Beispiel zur Verfügung innerhalb des W3C-Dokumentation selbst.
  2. Hier ist eine andere Implementierung von Rodney Rehm, die auch überwacht tab.
  3. Greg Kraus hat eine Bibliothek, die dies erreicht. Seine Implementierung verwaltet eine Liste von Selektoren, die für alle gültig fokussierbare Elemente.
  4. Eine weitere leichtgewichtige Bibliothek zum erstellen Barrierefreier modals.

Das ist alles für dieses experiment. Wenn Sie mochte diesen trick, Sie können mir Folgen, wo ich mehr teilen, Artikeln und side-Projekte von mir.