En CSS Tilnærming til Felle Fokus på Innsiden av et Element

0
42

Jeg har nylig lest denne artikkelen av Keith Grant som innførte nylig ankommet <dialogboksen>. Begeistret for denne nye UI element, jeg umiddelbart satte seg ned for å eksperimentere med det å se hvordan det kan brukes effektivt som en modal — den mest vanlige bruken av det. Mens du eksperimenterer, oppdaget jeg en ryddig CSS lure på hvordan å felle fokus i <dialog – > – element, en felles tilgjengelighet kravet for modals, og en notorisk vanskelig.

Hva er fokus fangst?

Først et sitat fra W3C dokumentasjon om hva som skal skje etter et tastetrykk i en dialog:

– Fanen:

  • Flytter fokus til neste tab-stand element i dialogen.
  • Hvis fokus er på den siste kategorien-stand element i dialogen, flytter fokuset til den første kategorien-stand element i dialogen.

Shift + Tab

  • Flytter fokus til forrige fane-stand element i dialogen.
  • Hvis fokus er på den første kategorien-stand element i dialogen, flytter fokuset til den siste kategorien-stand element i dialogen.

For å oppsummere, når du er i en dialog, å trykke Tab eller Skift+Tab skulle sykle fokus i dialogen kun—blant fokuserbart elementer inne i dialogboksen.

Dette gir mening fordi når en dialog er åpen, kan en bruker er i samspill bare inne i den og la fokusere for å unnslippe utenfor dialogen vil i hovedsak være å blande sammenhenger og muligens skape en tilstand der brukeren ikke vet hvilke element som er i fokus.

Så, gå tilbake til ideen om en modal, vår forventning ville være at tabbe innsiden av modale ville bare fokusere på elementer innsiden av modal. Noe utenfor rammen av modale ville være ute av omfang fordi fanen er bare opptatt av hva som er på innsiden av det. Dette er hva vi mener med fokus fangst.

En gjennomføring med JavaScript

Hvis vi skulle implementere fokus fangst inni en <dialogboksen>, den mest vanlige tilnærmingen ville være å gjøre følgende når dialogboksen åpnes:

1. Grip alle fokuserbart/tappable elementer inne i dialogboksen.
2. Lytt til Tab og Shift+Tab-tastetrykk og manuelt fokus neste eller forrige element, henholdsvis.
3. Hvis tastetrykk skjer på den første fokuserbart element, deretter fokusere siste fokuserbart element i kjeden og vice versa.

På denne måten kan vi lage en løkke på fokus som brukeren trykker Tab eller Shift+Tab. Se denne W3C-kodebit som et eksempel på hvordan dette kan bli kontaktet med JavaScript. Du vil se det er ganske litt av JavaScript.

Enter :fokus-i

Tilbake til min eksperimentere med nye <dialog – > – element. Når du tenker om å fokusere fangst, en CSS pseudo-klasse (også aller siste i nettlesere) umiddelbart kom til mitt sinn : :fokus-innenfor.

Hvis du ikke har hørt om det før, det representerer et element som har fått fokus eller inneholder et element som har fått fokus. Så, for eksempel, har du en <div> og inni det er en input-elementet. Hvis du ønsker å stil som <div> når den inneholdt inngang har fokus, kan du gjøre det slik:

div:fokus-i {
border: 2px solid rød;
}

Se Penn :fokus-i løpet av Geoff Graham (@geoffgraham) på CodePen.

CSS lure til å fokusere fangst

La oss utnytte :fokus-både innenfor og CSS overganger til å gjennomføre en grunnleggende fokus felle innsiden av en <dialog – > – element.

For å oppsummere, her er hvordan kunsten fungerer. Når fokus er ikke i dialog, og dialogen er åpen), vi:

  1. trigger en CSS-overgang
  2. oppdage at overgangen blir gjennomført i JavaScript
  3. fokus det første elementet i dialogboksen

Men først la oss få satt opp. Her er det grunnleggende i dialogboksen og åpne funksjonalitet:

<- knappen id=”knappen”>Åpner dialogboksen</button>
<dialog id=”modale”>
<form action=””>
<label>
<input type=”text” /> Brukernavn
</label>
<label>
<input type=”password” /> Passord
</label>
<input type=”submit” value=”Send” />
</form>
</dialog ->
knappen.onclick = () => {
modal.showModal();
}

Det vi går. Ved å klikke på knappen bør åpne dialogboksen. Bare dette mye kode som kreves for å gjøre en grunnleggende arbeider modal ved hjelp av den nye <dialog – > – element!

Se Penn Enkle <dialogboksen&rt; av Geoff Graham (@geoffgraham) på CodePen.

Hvis du åpnet dialogen i eksemplet ovenfor, og begynte å tabbe flere ganger, du har kanskje allerede lagt merke til problemet: fokus starter med elementer i dialogboksen, men så etterlater en gang det siste elementet i dialogboksen har gått.

Dette er kjernen av vår triks. Vi liksom må sende mistet fokus oppdaget :fokus-løpet over til JavaScript, slik at vi kan sende fokus tilbake til dialogen. Dette er der hvor CSS-overganger kommer inn i bildet. En CSS-overgangen er noe som skjer gjennom CSS, men avgir hendelser i JavaScript for. I vårt tilfelle, kan vi utløse en overgang på enhver eiendom med et ubetydelig (fordi det ikke spiller noen rolle i vårt tilfelle) visuell forskjell, og lytte etter overgangen ferdigstillelse i JavaScript.

Merk at vi trenger å utløse denne overgangen når dialogboksen åpne, men har ikke fokus på innsiden.

dialogboksen {
background-color: rgb(255, 255, 255);
}
dialogboksen[åpne]:ikke(:fokus-i) {
background-color: rgb(255, 255, 254);
overgang: background-color 0.01 s;
}

La oss se hva som CSS gjør.

  1. Vi legger background-color våre valg i dialogboksen. Dette er ikke nødvendig, men sikrer at vi har den samme bakgrunnsfargen på tvers av nettlesere.
  2. Dialogboksen[åpne]:ikke(:fokus-i) velgeren gjelder når dialogboksen åpne, men har ikke fokus på eller inne i den. Dette fungerer fordi native <dialog – > – element setter en åpen attributt når det er åpent.
  3. Inne i denne regel, kan vi endre bakgrunn-farge ved et minimum. Dette er den minste endring som er nødvendig for å utløse en CSS-animasjoner og på samme tid ikke forårsaker noen visuelle forskjellen for brukeren (husk dette er en dummy overgang). Vi har også sett overgangen eiendom med en svært liten varighet fordi vi vil ha det ferdig så fort som mulig og få påvist i JavaScript.

En touch av JavaScript

Nå er alt vi trenger å gjøre er å oppdage slutten av vår utløst CSS overgang og fokus tilbake til den første element i den sperrende, som så:

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

Vi legger en transitionend lytteren på modal og inne innb., fokuserer vi den første inngang inne i modal. Ferdig!

Se Pen Dialog fokus fangst med CSS ved Kushagra Gour (@chinchang) på CodePen.

Begrensninger

Dette er en rask eksperiment som jeg gjorde for å lage en fungerende proof-of-concept av fokus fangst med :fokus-i pseudo-klassen. Det har flere begrensninger i forhold til egne JavaScript-løsninger for å oppnå dette. Likevel, noe er bedre enn ingenting!

Her er et par ting som dette implementering mangler:

  1. I henhold til W3C retningslinjer, fokus bør sykle på fokuserbart element. Men vi er alltid med fokus på den første input-elementet. Dette er fordi uten å skrive mer JavaScript, vi kan ikke vite om fokus var tapt fra første eller siste element.
  2. Vi er alltid med fokus tilbake til den første input-elementet. Men det er mange flere fokuserbart HTML-elementer som kan være til stede før inngang eller kanskje det er ikke inngang element på alle inne i modal. Igjen, fullverdig JavaScript løsninger oppdage og vedlikeholde en liste over alle fokuserbart elementer og fokusere riktig.

Bedre (JavaScript) implementeringer av fokus fangst

  1. Som nevnt tidligere, en arbeider for eksempel er tilgjengelige inne i W3C dokumentasjon i seg selv.
  2. Her er en annen implementering av Rodney Rehm som også hører til kategorien.
  3. Greg Kraus har et bibliotek som oppnår dette. Hans gjennomføring vedlikeholder en liste av velgere for alle gyldig fokuserbart elementer.
  4. En mer lett-biblioteket for å opprette tilgjengelige modals.

Det er alt for dette eksperimentet. Hvis du likte dette trikset, kan du følge meg på hvor jeg deler flere artikler og siden prosjektene mine.