Dostępność
Czym jest dostępność?
Pojęcie dostępności stron internetowych (określanej również a11y od ang. accessibility) zostało zaprojektowane i stworzone z myślą o internecie przystępnym dla wszystkich. Wspieranie dostępności jest niezbędne, aby umożliwić technologiom asystującym poprawną interpretację stron.
React w pełni wspiera budowanie dostępnych dla wszystkich stron internetowych, często z wykorzystaniem standardowych technik HTML.
Standard oraz wytyczne
WCAG
Web Content Accessibility Guidelines dostarcza zbiór wytycznych, jak tworzyć poprawne oraz dostępne dla wszystkich strony internetowe.
Poniższe listy kontrolne WCAG zawierają przegląd:
- Lista kontrolna WCAG stworzona przez Wuhcag
- Lista kontrolna WCAG stworzona przez WebAIM
- Lista kontrolna projektu A11Y
WAI-ARIA
Dokument Web Accessibility Initiative - Accessible Rich Internet Applications zawiera listę technik pomagających w budowaniu w pełni dostępnych aplikacji javascriptowych.
Warto zaznaczyć, że wszystkie atrybuty HTML aria-* są w pełni wspierane przez JSX. Mimo że większość tagów oraz atrybutów DOM w Reakcie zapisujemy w notacji camelCase, to te związane z dostępnością powinny być zapisywane z wykorzystaniem myślników (znanych również jako kebab-case, lisp-case itp.), ponieważ są one traktowane jak zwykłe atrybuty HTML.
<input
type="text"
aria-label={etykieta} aria-required="true" onChange={obserwatorZdarzenia}
value={wartoscPola}
name="imie"
/>Semantyczny HTML
Semantyczny HTML jest podstawą dostępności aplikacji webowych. Wykorzystując różne elementy HTML, które wzmacniają znaczenie informacji na naszych stronach, bardzo często możemy stworzyć w pełni dostępną stronę bez dodatkowego nakładu pracy.
Czasem łamiemy zasady semantycznego HTML, kiedy dodajemy dodatkowy element div do naszego kodu JSX, aby uruchomić aplikację. Dzieje się tak zwłaszcza kiedy pracujemy z listami (<ol>, <ul> czy <dl>) oraz tabelami <table>.
W takim przypadkach powinniśmy korzystać z fragmentów reactowych, które pozwalają na grupowanie elementów.
Przykład:
import React, { Fragment } from 'react';
function ListItem({ item }) {
return (
<Fragment> <dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment> );
}
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
<ListItem item={item} key={item.id} />
))}
</dl>
);
}Możesz mapować kolekcje elementów do tablicy fragmentów, zupełnie jak w przypadku innych typów elementów:
function Glossary(props) {
return (
<dl>
{props.items.map(item => (
// Fragmenty zawsze powinny mieć ustawioną wartość `key` podczas mapowania kolekcji
<Fragment key={item.id}> <dt>{item.term}</dt>
<dd>{item.description}</dd>
</Fragment> ))}
</dl>
);
}Jeśli nie chcesz przekazywać żadnych dodatkowych właściwości do Fragmentu, wówczas możesz użyć skróconej składni. Upewnij się, że wspomniany zapis jest wspierany przez używane przez ciebie środowisko.
function ListItem({ item }) {
return (
<> <dt>{item.term}</dt>
<dd>{item.description}</dd>
</> );
}Więcej informacji znajdziesz w dokumentacji fragmentów.
Dostępne formularze
Nadawanie etykiet
Każdy element kontrolujący formularz, taki jak input czy textarea, powinien być etykietowany w przystępny sposób. Etykieta powinna dobrze opisywać pole tekstowe i być widoczna dla czytników ekranowych.
Poniższe zasoby opisują, jak robić to poprawnie:
- W3C - etykietowanie elementów
- WebAim - etykietowanie elementów
- Grupa Paciello wyjaśnia przystępność nazw
Chociaż tych standardowych praktyk HTML-owych można używać bezpośrednio w Reakcie, zauważ, że atrybut for jest w składni JSX zapisywany jako htmlFor:
<label htmlFor="imiePoleTekstowe">Imię:</label><input id="imiePoleTekstowe" type="text" name="imie"/>Powiadamianie użytkownika o błędach
W sytuacji zgłoszenia błędu, komunikaty muszą być zrozumiałe dla wszystkich użytkowników. Poniższe linki pokazują, jak wyświetlić błędy w sposób zrozumiały dla czytników ekranowych.
Kontrola fokusa
Upewnij się, że twoją aplikację internetową można w pełni obsługiwać za pomocą samej klawiatury:
Fokus klawiaturowy a kontur
Fokus klawiaturowy odnosi się do bieżącego elementu w DOM, który został wybrany poprzez zdarzenia wywołane przez klawiaturę. Zazwyczaj oznaczany jest za pomocą konturu, podobnego do tego na obrazku poniżej:
Jeśli decydujesz się na usunięcie konturu, np. ustawiając właściwość CSS outline: 0, nie zapomnij zastąpić go inną implementacją konturu.
Przejście do treści
Zapewnij mechanizm umożliwiający użytkownikom pominięcie sekcji nawigacji na stronie, ponieważ ułatwia on i przyspiesza nawigowanie z wykorzystaniem klawiatury.
Łącza typu “Przejdź do treści” lub “Pomiń nawigację” to specjalne, ukryte linki nawigacyjne, które stają się widoczne tylko wtedy, gdy użytkownicy klawiatury wchodzą w interakcję ze stroną. Są bardzo łatwe w implementacji z wykorzystaniem wewnętrznych kotwic oraz odrobiny stylowania:
Używaj również elementów i punktów orientacyjnych, takich jak <main> i <aside>, aby rozgraniczyć sekcje strony. Dzięki nim technologie wspierające pozwalają użytkownikowi na szybkie przemieszczanie się między sekcjami.
Przeczytaj więcej o wykorzystaniu tych elementów w celu zwiększenia dostępności:
Programowe zarządzanie fokusem
Nasze aplikacje Reactowe nieustannie modyfikują HTML DOM w czasie działania, co chwilami prowadzi do utraty konturu aktywnego elementu lub ustawienia go na nieoczekiwany element. Aby to naprawić, musimy ręcznie ustawić fokus we właściwym miejscu. Przykładowo, jeśli użytkownik zamknie okno modalne, fokus mógłby zostać przeniesiony na przycisk, który to okno otworzył.
Dokumentacja MDN opisuje dokładniej, w jaki sposób możemy tworzyć widżety javascriptowe z obsługą klawiatury.
W Reakcie, aby ustawić fokus, możemy posłużyć się mechanizmem referencji do elementu DOM.
Aby móc skorzystać z tego mechanizmu, w kodzie JSX wybranego komponentu tworzymy referencję ref do elementu :
class CustomTextInput extends React.Component {
constructor(props) {
super(props);
// Stwórz referencję do elementu DOM this.textInput= React.createRef(); }
render() {
// Użyj funkcji zwrotnej `ref`, aby zapisać referencję do pola tekstowego // we właściwości instancji komponentu (na przykład this.textInput). return (
<input
type="text"
ref={this.textInput} />
);
}
}Wówczas, w razie potrzeby, możemy przenieść fokus na inny element naszego komponentu:
focus() {
// Jawne przeniesienie fokusa na pole tekstowe przy użyciu natywnego interfejsu DOM
// Uwaga: korzystamy z "current", aby uzyskać dostęp do węzła DOM
this.textInput.current.focus();
}Czasami komponent nadrzędny musi ustawić fokus na element komponentu podrzędnego. Możemy to zrobić poprzez przesłanie referencji “w górę” do komponentu nadrzędnego za pomocą specjalnej właściwości nadanej komponentowi podrzędnemu.
function CustomTextInput(props) {
return (
<div>
<input ref={props.inputRef} /> </div>
);
}
class Parent extends React.Component {
constructor(props) {
super(props);
this.inputElement = React.createRef(); }
render() {
return (
<CustomTextInput inputRef={this.inputElement} /> );
}
}
// Teraz możesz ręcznie ustawiać fokus, kiedy to potrzebne.
this.inputElement.current.focus();Kiedy używasz HOC-a do rozszerzenia komponentów, zaleca się przekazanie referencji do opakowanego komponentu przy użyciu funkcji forwardRef, która wbudowana jest w Reacta. Jeśli wybrany HOC z którejś zewnętrznej biblioteki nie implementuje takiego przekierowania, można użyć powyższego wzorca jako wyjście awaryjne.
Doskonałym przykładem zarządzania fokusem jest biblioteka react-aria-modal. Jest to stosunkowo rzadki przykład w pełni dostępnego okna modalnego. Nie tylko ustawia początkowy fokus na przycisku zamykającym okno (uniemożliwiając tym samym użytkownikowi klawiatury przypadkowe aktywowanie akcji akceptującej) i zatrzymuje fokus klawiaturowy wewnątrz okna, lecz dodatkowo po zamknięciu przywraca fokus z powrotem na element, który zainicjował otwarcie okna.
Uwaga:
Chociaż jest to bardzo ważna technika zapewniająca dostępność, należy stosować jej z umiarem. Użyj jej, aby skorygować naturalną “drogę” fokusa w aplikacji, ale nie próbuj przewidzieć, jak użytkownicy będą chcieli korzystać z aplikacji i nie wymuszaj własnej “drogi”.
Zdarzenia myszy i wskaźnika
Upewnij się, że wszystkie funkcje dostępne dla korzystających z myszy lub wskaźnika są również osiągalne za pomocą samej klawiatury. Poleganie na samych urządzeniach wskazujących prowadzi często do sytuacji, w których użytkownicy klawiatury nie mogą w ogóle korzystać z aplikacji.