Атрибут tabindex тега <dialog>
Описание
Атрибут tabindex определяет порядок перехода между элементами при навигации с помощью клавиши Tab внутри диалогового окна <dialog>.
<dialog id="focusDialog">
<h3>Диалог с управлением фокуса</h3>
<button tabindex="3">Кнопка 3</button>
<button tabindex="1" autofocus>Кнопка 1 (автофокус)</button>
<button tabindex="2">Кнопка 2</button>
<a href="#" tabindex="4">Ссылка</a>
<button tabindex="-1">Недоступная кнопка</button>
</dialog>
Значения атрибута:
| Значение | Поведение | Использование |
|---|---|---|
tabindex="0" |
Элемент включается в естественный порядок табуляции | Для добавления элементов в поток навигации |
tabindex="-1" |
Элемент исключается из табуляции, но может получать фокус программно | Для временно скрытых или управляемых элементов |
tabindex="1+" |
Определяет явный порядок табуляции (не рекомендуется) | Особые случаи, требующие точного контроля |
Лучшие практики для диалогов:
<dialog id="accessibleDialog">
<h3 tabindex="0">Заголовок диалога (доступен для фокуса)</h3>
<div tabindex="0" class="scrollable-content">
Прокручиваемое содержимое с возможностью фокуса
</div>
<button tabindex="0" autofocus>Основное действие</button>
<button tabindex="0">Дополнительное действие</button>
<button tabindex="-1" class="secondary-action">Скрытое действие</button>
</dialog>
<style>
.scrollable-content {
max-height: 200px;
overflow-y: auto;
padding: 10px;
border: 1px solid #eee;
}
</style>
Программное управление фокусом:
<dialog id="programmaticDialog">
<h3>Управление фокусом</h3>
<button id="firstBtn" tabindex="0">Первый элемент</button>
<button id="lastBtn" tabindex="0">Последний элемент</button>
<button id="hiddenBtn" tabindex="-1">Скрытая кнопка</button>
</dialog>
<script>
const dialog = document.getElementById('programmaticDialog');
// Установка фокуса на скрытый элемент
document.getElementById('hiddenBtn').addEventListener('click', () => {
document.getElementById('hiddenBtn').focus();
});
// Ловушка фокуса внутри диалога
dialog.addEventListener('keydown', (e) => {
if (e.key === 'Tab') {
const focusable = dialog.querySelectorAll('[tabindex="0"]');
if (focusable.length === 0) return;
const first = focusable[0];
const last = focusable[focusable.length - 1];
if (e.shiftKey && document.activeElement === first) {
last.focus();
e.preventDefault();
} else if (!e.shiftKey && document.activeElement === last) {
first.focus();
e.preventDefault();
}
}
});
</script>
Особенности доступности:
- Всегда обеспечивайте визуальный индикатор фокуса
- Первый фокусируемый элемент должен быть логичным (обычно кнопка "Закрыть")
- Используйте
autofocusдля основного действия - Обеспечьте возможность закрытия диалога клавишей Esc
- Возвращайте фокус на элемент, вызвавший диалог, после закрытия
Возврат фокуса:
<button id="openDialogBtn">Открыть диалог</button>
<dialog id="returnFocusDialog">
<h3>Диалог с возвратом фокуса</h3>
<button onclick="this.closest('dialog').close()">Закрыть</button>
</dialog>
<script>
const opener = document.getElementById('openDialogBtn');
const dialog = document.getElementById('returnFocusDialog');
opener.addEventListener('click', () => {
dialog.showModal();
});
dialog.addEventListener('close', () => {
opener.focus();
});
</script>
Примечание: Правильное управление фокусом критически важно для доступности диалоговых окон. Всегда тестируйте навигацию с помощью клавиатуры и убедитесь, что диалог не создает "ловушку фокуса", из которой пользователь не может выйти без мыши.