Клавиатурная навигация — важная часть доступности пользовательского интерфейса. Она обеспечивает управление элементами интерфейса без использования мыши. В веб-приложениях это особенно важно для пользователей с ограниченными возможностями, а также для тех, кто предпочитает работать с клавиатурой по соображениям скорости и удобства.
В интерфейсных библиотеках, включая Element Plus, поддержка клавиатурной навигации встроена во многие компоненты. Корректная реализация позволяет:
Element Plus использует стандартные механизмы браузера и дополняет их собственной логикой обработки клавиш.
tabindexКлавиатурная навигация в браузере основана на понятии фокуса. Фокус указывает на элемент, который будет получать события клавиатуры.
По умолчанию фокус получают:
button)input, textarea)a)Для управления порядком фокусировки используется атрибут
tabindex.
tabindex| Значение | Поведение |
|---|---|
0 |
элемент участвует в естественном порядке фокуса |
-1 |
элемент не участвует в навигации Tab, но может получить фокус программно |
>0 |
явный порядок фокуса (используется редко) |
Пример использования:
<template>
<el-button tabindex="0">Кнопка 1</el-button>
<el-button tabindex="0">Кнопка 2</el-button>
</template>
Element Plus корректно обрабатывает фокус внутри компонентов, поэтому
дополнительная настройка tabindex требуется редко.
Клавиша Tab является основным инструментом клавиатурной навигации.
При нажатии:
Tab — переход к следующему элементуShift + Tab — переход к предыдущему элементуВо многих компонентах Element Plus эта логика уже реализована. Например:
Пример формы:
<template>
<el-form>
<el-form-item label="Имя">
<el-input />
</el-form-item>
<el-form-item label="Email">
<el-input />
</el-form-item>
<el-button type="primary">Отправить</el-button>
</el-form>
</template>
Навигация:
el-inputTab — переход ко второмуTab — переход к кнопкеДля реализации расширенной клавиатурной логики используются события клавиатуры:
keydownkeyupkeypress (устаревшее)В Vue обработчики событий добавляются через директиву
v-on или сокращённую запись @.
Пример:
<el-input @keydown="handleKey" />
Метод обработки:
function handleKey(event) {
if (event.key === 'Enter') {
console.log('Нажата клавиша Enter')
}
}
Vue поддерживает модификаторы клавиш, упрощающие код.
Пример:
<el-input @keydown.enter="submit" />
Компонент el-select полностью поддерживает управление с
клавиатуры.
Основные действия:
| Клавиша | Действие |
|---|---|
| Enter | открыть список |
| ↓ | перейти к следующему элементу |
| ↑ | перейти к предыдущему |
| Enter | выбрать элемент |
| Esc | закрыть список |
Пример:
<template>
<el-select v-model="value" placeholder="Выберите">
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</template>
const value = ref('')
const options = [
{ value: '1', label: 'Первый' },
{ value: '2', label: 'Второй' },
{ value: '3', label: 'Третий' }
]
Поведение:
Tab устанавливает фокус на поле.Enter открывает список.Enter подтверждает выбор.Компонент el-menu реализует вертикальную и
горизонтальную навигацию с клавиатуры.
Основные клавиши:
| Клавиша | Действие |
|---|---|
| ↑ | предыдущий пункт |
| ↓ | следующий пункт |
| → | открыть подменю |
| ← | закрыть подменю |
| Enter | активировать пункт |
Пример меню:
<template>
<el-menu>
<el-menu-item index="1">Главная</el-menu-item>
<el-menu-item index="2">Документы</el-menu-item>
<el-sub-menu index="3">
<template #title>Настройки</template>
<el-menu-item index="3-1">Профиль</el-menu-item>
<el-menu-item index="3-2">Безопасность</el-menu-item>
</el-sub-menu>
</el-menu>
</template>
Навигация осуществляется без мыши:
Enter активирует пунктEsc закрывает вложенные менюКомпонент el-dialog автоматически управляет фокусом.
Поведение при открытии:
Tab происходит только внутри окнаEsc закрывает диалогПример:
<template>
<el-button @click="visible = true">
Открыть
</el-button>
<el-dialog v-model="visible" title="Диалог">
<el-input placeholder="Введите текст" />
<template #footer>
<el-button @click="visible = false">
Отмена
</el-button>
<el-button type="primary">
Подтвердить
</el-button>
</template>
</el-dialog>
</template>
Element Plus реализует focus trap — механизм, не позволяющий фокусу выйти за пределы диалога.
Компонент el-table поддерживает навигацию и
взаимодействие через клавиатуру при использовании дополнительных
обработчиков.
Пример реализации:
<el-table
:data="tableData"
@keydown.native="handleKey"
tabindex="0"
>
Обработчик:
function handleKey(event) {
if (event.key === 'ArrowDown') {
selectNextRow()
}
if (event.key === 'ArrowUp') {
selectPrevRow()
}
}
Такая логика позволяет реализовать:
Иногда требуется вручную переместить фокус на конкретный элемент.
В Vue это делается через ref.
Пример:
<template>
<el-input ref="inputRef" />
<el-button @click="focusInput">
Фокус
</el-button>
</template>
const inputRef = ref()
function focusInput() {
inputRef.value.focus()
}
Это используется в сценариях:
Горячие клавиши ускоряют работу с интерфейсом.
Пример реализации:
window.addEventListener('keydown', (event) => {
if (event.ctrlKey && event.key === 's') {
event.preventDefault()
saveDocument()
}
})
Возможные комбинации:
| Комбинация | Назначение |
|---|---|
| Ctrl + S | сохранить |
| Ctrl + Enter | отправить форму |
| Esc | закрыть окно |
| Ctrl + K | открыть поиск |
При реализации горячих клавиш важно избегать конфликтов со стандартными сочетаниями браузера.
Element Plus использует ARIA-атрибуты, улучшающие доступность интерфейса.
Основные атрибуты:
| Атрибут | Назначение |
|---|---|
aria-label |
описание элемента |
aria-expanded |
состояние раскрытия |
aria-hidden |
скрытие элемента |
role |
тип элемента |
Пример:
<el-button aria-label="Закрыть окно">
Закрыть
</el-button>
ARIA помогает:
Проблема:
<div @click="openMenu">Меню</div>
Такой элемент не получает фокус.
Решение:
<div tabindex="0" @click="openMenu">
Меню
</div>
preventDefaultЕсли не отменить стандартное действие браузера, возможны конфликты.
Пример:
function handleKey(event) {
if (event.key === 'Enter') {
event.preventDefault()
submit()
}
}
После изменения состояния компонента Vue может перерисовать элемент.
Если фокус был внутри компонента, он может исчезнуть.
Решение — восстановить его:
nextTick(() => {
inputRef.value.focus()
})
Эффективная клавиатурная навигация в интерфейсе достигается соблюдением нескольких принципов:
1. Все интерактивные элементы должны быть доступны через Tab
Кнопки, ссылки, поля ввода, меню.
2. Логичный порядок фокуса
Переход должен соответствовать визуальному расположению элементов.
3. Поддержка стандартных клавиш
Пользователи ожидают привычное поведение:
4. Явное состояние фокуса
Фокус должен быть визуально заметен.
:focus {
outline: 2px solid #409eff;
}
5. Ограничение фокуса в модальных окнах
Focus trap предотвращает случайный переход за пределы диалога.
Element Plus уже реализует клавиатурную поддержку для большинства компонентов:
| Компонент | Поддержка клавиатуры |
|---|---|
| Input | ввод и подтверждение |
| Select | навигация стрелками |
| Menu | стрелки и Enter |
| Dialog | Tab и Esc |
| Dropdown | стрелки |
| DatePicker | стрелки и Enter |
Поэтому в большинстве случаев разработчику требуется только: