Связывайте ответ с браузером, доступностью, производительностью и пользовательским состоянием — именно там видна зрелость frontend-инженера.
Вопросы и ответы
8 подробных ответов
01Что такое доступность (accessibility, a11y) и почему она важна?
junior
Короткий ответ: Доступность (a11y) — это проектирование продуктов так, чтобы ими могли пользоваться люди с нарушениями зрения, слуха, моторики и когнитивными особенностями. Она важна по трём причинам: этической (люди), деловой (шире аудитория) и юридической (WCAG, ADA, European Accessibility Act).
Подробно:
- Люди — около 15% населения живёт с какой-либо инвалидностью; временные (сломанная рука) и ситуативные (яркое солнце, шумное метро) ограничения касаются всех.
- Бизнес — больше пользователей, лучше SEO (семантика = понятная структура), меньше отказов.
- Закон — WCAG 2.x де-факто стандарт; в США — ADA/Section 508, в ЕС — EAA; иски за недоступные сайты реальны.
| Нарушение | Барьер | Решение |
|---|---|---|
| Зрение | не видит экран | скринридер, контраст, alt |
| Слух | не слышит звук | субтитры, транскрипты |
| Моторика | не пользуется мышью | доступность с клавиатуры |
| Когнитивные | сложный интерфейс | простой язык, ясная структура |
⚠️ Частая ошибка: считать доступность «фичей для меньшинства» — на деле она улучшает UX для всех (эффект срезанного бордюра).
02В чём разница между семантическим HTML и ARIA, и в чём «первое правило ARIA»?
middle
Короткий ответ: Семантический HTML несёт роль, состояние и поведение «из коробки» (button, nav, input), а ARIA лишь добавляет семантику там, где нативного элемента нет. Первое правило ARIA: если есть подходящий нативный элемент — используй его, а не ARIA.
Подробно:
- ARIA даёт три вещи: роли (role="dialog"), состояния (aria-expanded, aria-checked) и свойства (aria-label, aria-controls).
- ARIA ничего не делает сама — она лишь меняет дерево доступности; обработку клавиатуры и фокус пишешь руками.
- Нативный
<button>уже фокусируем, реагирует на Enter/Space и объявляется как кнопка —<div role="button">всё это требует доделывать вручную.
| Задача | Нативно (предпочтительно) | Через ARIA |
|---|---|---|
| Кнопка | <button> |
<div role="button" tabindex="0"> |
| Навигация | <nav> |
role="navigation" |
| Чекбокс | <input type="checkbox"> |
role="checkbox" aria-checked |
| Заголовок | <h1>–<h6> |
role="heading" aria-level |
⚠️ Частая ошибка: навешивать избыточную ARIA-роль на нативный элемент (<button role="button">) или, хуже, переопределять её (<h1 role="button">) — это ломает семантику.
03Как обеспечить доступность с клавиатуры: порядок фокуса, tabindex, видимый фокус и skip-ссылки?
middle
Короткий ответ: Всё интерактивное должно достигаться с клавиатуры в логичном порядке, с видимым индикатором фокуса. Порядок фокуса задаётся порядком в DOM; tabindex="0" включает элемент в таб-порядок, -1 делает фокусируемым только программно, а положительные значения использовать нельзя.
Подробно:
- Порядок фокуса — следует за DOM; не ломай его CSS-ом (order, flex-direction).
- tabindex —
0обычный поток,-1фокус из JS (например, на заголовок диалога), положительный — антипаттерн. - Видимый фокус — никогда не убирай
outline: noneбез замены (:focus-visible). - Skip-ссылка — первая в DOM, позволяет перепрыгнуть навигацию к контенту.
- Ловушка фокуса — нужна только внутри модалок: Tab циклится внутри, Esc закрывает.
Tab → [Skip to content] (скрыта до фокуса)
↓
[Логотип] → [Навигация] → [Поиск]
↓ (или Skip перепрыгивает сюда)
[ Главный контент: ссылки, кнопки, поля ]
↓
[ Футер ]
⚠️ Частая ошибка: tabindex="5" ради «правильного» порядка — положительный tabindex ломает естественный поток для всех; чините порядок в DOM.
04Назовите основы WCAG: принципы POUR, уровни A/AA/AAA и требования к контрасту.
middle
Короткий ответ: WCAG строится на четырёх принципах POUR: Воспринимаемость, Управляемость, Понятность, Надёжность (Perceivable, Operable, Understandable, Robust). Критерии делятся на уровни A, AA (рабочий минимум) и AAA. Контраст обычного текста должен быть не ниже 4.5:1, для крупного текста и UI-элементов — 3:1.
Подробно:
- Perceivable — alt, субтитры, контраст.
- Operable — клавиатура, отсутствие ловушек, время на действия.
- Understandable — понятный язык, предсказуемость, помощь в формах.
- Robust — валидная разметка, работа со вспомогательными технологиями.
| Что | Минимум (AA) | AAA |
|---|---|---|
| Обычный текст (<18.66px bold / <24px) | 4.5:1 | 7:1 |
| Крупный текст (≥18.66px bold / ≥24px) | 3:1 | 4.5:1 |
| UI и графика (границы, иконки) | 3:1 | — |
⚠️ Частая ошибка: проверять контраст «на глаз». Контраст считается по формуле относительной яркости; светло-серый текст на белом почти всегда проваливает 4.5:1.
05Как скринридеры читают страницу и как принимать решения об alt-тексте?
middle
Короткий ответ: Скринридер озвучивает не DOM, а дерево доступности — упрощённую модель, где у каждого элемента есть роль, доступное имя (accessible name) и состояние. Alt-текст формирует имя изображения: информативные картинки описывают, декоративные получают пустой alt="".
Подробно:
- Дерево доступности — браузер строит его из HTML+ARIA; скринридер ходит по нему.
- Доступное имя — берётся из содержимого,
alt,<label>,aria-label/aria-labelledby. - Решение об alt: информативное → краткое описание сути; декоративное →
alt=""(скрыть); функциональное (иконка-ссылка) → описывает действие, не картинку.
<!-- Информативное: что важно на картинке -->
<img src="chart.png" alt="Продажи выросли на 30% в Q2">
<!-- Декоративное: пустой alt, чтобы скринридер пропустил -->
<img src="divider.svg" alt="">
<!-- Функциональное: описывай действие -->
<a href="/cart"><img src="cart.svg" alt="Корзина"></a>
⚠️ Частая ошибка: alt вида «изображение» или «img_1234.jpg», либо отсутствие alt у декоративной картинки — скринридер зачитает имя файла.
06Как построить доступное модальное окно (а также вкладки и аккордеон) по WAI-ARIA APG?
senior
Короткий ответ: Для каждого виджета APG задаёт нужные роли, состояния и управление фокусом. Модалка: role="dialog" aria-modal="true" плюс aria-labelledby, перенос фокуса внутрь, ловушка фокуса и Esc для закрытия с возвратом фокуса на триггер.
Подробно:
- Dialog —
role="dialog",aria-modal="true",aria-labelledbyна заголовок; при открытии фокус внутрь, при закрытии — назад на кнопку-триггер. - Tabs —
role="tablist"→role="tab"сaria-selectedиaria-controls; контент вrole="tabpanel"; переключение стрелками. - Accordion — кнопка-заголовок с
aria-expandedиaria-controlsна секцию контента.
<div role="dialog" aria-modal="true" aria-labelledby="title">
<h2 id="title">Удалить аккаунт?</h2>
<button>Отмена</button>
<button>Удалить</button>
</div>
<!-- Фокус: внутрь при открытии, Tab циклится внутри,
Esc закрывает, фокус возвращается на триггер -->
⚠️ Частая ошибка: «модалка», после открытия которой фокус остаётся на фоне, а контент за ней доступен скринридеру и Tab-у — нужен перенос фокуса и aria-modal/inert для фона.
07Как сделать доступную форму: связывание лейблов, группировка и сообщения об ошибках?
middle
Короткий ответ: Каждое поле должно иметь связанный <label> (через for/id или обёртку), родственные поля группируются <fieldset>+<legend>, а ошибки связываются с полем через aria-describedby и помечаются aria-invalid="true".
Подробно:
- Лейбл —
<label for>явно связан с полем; placeholder лейбл не заменяет. - Группировка — радиокнопки и связанные поля в
<fieldset>с<legend>. - Ошибки — текст ошибки получает id, поле ссылается на него через
aria-describedby;aria-invalidсообщает о невалидности; для динамики используйтеaria-live.
<label for="email">Эл. почта</label>
<input id="email" type="email"
aria-describedby="email-err"
aria-invalid="true" required>
<p id="email-err">Введите корректный адрес.</p>
⚠️ Частая ошибка: использовать placeholder вместо лейбла — он исчезает при вводе, имеет слабый контраст и не всегда читается скринридером.
08Как тестировать доступность: что находят автоматические инструменты и что они пропускают?
senior
Короткий ответ: Автоматические инструменты (axe, Lighthouse, WAVE) ловят примерно 30–40% проблем — отсутствие alt, низкий контраст, дубли id, незаполненные лейблы. Остальное требует ручной проверки с клавиатуры и реального скринридера.
Подробно:
- Автоматизация — axe-core в CI/e2e, Lighthouse в аудите; быстро, но «зелёный ≠ доступно».
- Клавиатура — пройди весь поток только Tab/Shift+Tab/Enter/Esc/стрелки: достижимо ли всё, виден ли фокус, нет ли ловушек.
- Скринридер — VoiceOver (macOS/iOS), NVDA (Windows): осмысленны ли имена, объявляются ли состояния и ошибки.
| Найдёт авто-тест | Найдёт только человек |
|---|---|
Нет alt у <img> |
Осмысленность alt-текста |
| Контраст ниже нормы | Логичность порядка фокуса |
| Поле без лейбла | Понятность сообщений об ошибке |
Дубли id |
Корректность управления фокусом в модалке |
⚠️ Частая ошибка: считать «0 ошибок в Lighthouse» доказательством доступности — инструмент не оценивает смысл, контекст и реальный опыт работы со скринридером.
Источники
Источники и редакционная политика
Материалы RecallDeck сопоставлены с официальной документацией и открытыми публикациями компаний, когда первичный источник доступен. Мы не связаны с упомянутыми работодателями, не публикуем конфиденциальные задания и не продаём места в подборках. Формат найма может меняться — уточняйте его у рекрутера.
От чтения к воспроизведению
Отрепетируйте полный цикл интервью.
RecallDeck возвращает сложные темы по расписанию и помогает удерживать в памяти язык, SQL, архитектуру и поведенческие истории.