awesome-everything EN
↑ Обратно к восхождению

Архитектура фронтенда

Доступные формы: чтение кода

Суть Читаем реальные JSX-сниппеты — связь label, aria-live-регион ошибки, focus management и controlled input — и выбираем самое результативное исправление доступности.
Высота — путь к senior
НольJuniorMiddleSenior
Ты на senior-высоте — в орбите
◷ 14 min

Доступность формы решается в разметке и обработчике submit. Читайте каждый сниппет так, как читали бы его на ревью PR, и выбирайте исправление, которое senior-инженер делает первым.

Цель

Отработайте цикл ревью: заметьте сломанную связь label, live-регион, который ничего не озвучивает, пропущенное перемещение фокуса и controlled input, теряющий имя поля, — и выберите верное исправление.

Сниппет 1 — label, связанный ни с чем

function EmailField() {
  return (
    <div className="field">
      <label>Email</label>
      <input type="email" name="email" placeholder="you@example.com" />
    </div>
  );
}
Викторина

Screen reader озвучивает это поле как «edit text» без имени. В чём баг и как исправить?

Сниппет 2 — регион ошибки, который ничего не озвучивает

function Form() {
  const [error, setError] = useState("");
  return (
    <form onSubmit={validate}>
      <input id="zip" name="zip" aria-describedby="zip-err" />
      {error && <div id="zip-err" role="alert">{error}</div>}
      <button>Submit</button>
    </form>
  );
}
Викторина

Зрячие видят ошибку; многие пользователи screen reader ничего не слышат. Почему и какое минимальное исправление?

Сниппет 3 — обработчик submit, забывший про фокус

function handleSubmit(e) {
  e.preventDefault();
  const invalid = fields.filter((f) => !f.valid);
  invalid.forEach((f) => {
    f.el.setAttribute("aria-invalid", "true");
    setMessage(f.id, f.error); // пишет в постоянный live-регион
  });
  // ...и больше ничего
}
Викторина

aria-invalid выставлен, сообщения озвучиваются, но пользователи клавиатуры говорят, что форма «ничего не делает» на неудачном submit. Чего не хватает?

Сниппет 4 — controlled input, теряющий своё имя

function NameField({ value, onChange }) {
  return (
    <>
      <span className="lbl">Full name</span>
      <input
        value={value}
        onChange={(e) => onChange(e.target.value)}
      />
    </>
  );
}
Викторина

Это корректно управляемый (controlled) React-input, и всё же он проваливает доступность. В чём реальная проблема и исправление?

Итог

Любой баг доступности формы виден в разметке или обработчике submit: label должен быть связан через htmlFor/id или обёртку (placeholder или соседний span именем не являются); live-регион должен быть постоянным, чтобы изменение его текста было замечено; неудачный submit должен императивно переместить фокус на первое невалидное поле, а не просто выставить aria-invalid; и controlled-vs-uncontrolled ортогонально тому, есть ли у input accessible name. Читайте разметку, найдите сломанную связь или несдвинутый фокус и исправляйте это прежде всего.

Продолжить восхождение ↑Доступные формы: форма, полная с клавиатуры
хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.