Фокусировка элементов — ключевой аспект доступности и удобства взаимодействия с интерфейсом. В современных UI-библиотеках на SvelteKit управление фокусом реализуется через сочетание реактивности Svelte и специализированных утилит для контроля активного элемента.
Контроль активного элемента Каждый интерактивный
элемент (кнопки, ссылки, поля ввода) должен корректно получать и терять
фокус. В SvelteKit это достигается через директивы
bind:this для получения ссылки на DOM-узел и методы
.focus() / .blur().
<input bind:this={inputEl} placeholder="Введите текст" />
<button on:click={() => inputEl.focus()}>Фокус на поле</button>
<script>
let inputEl;
</script>Табуляция и порядок навигации Важным аспектом
является логика навигации с клавиатуры. Атрибут tabindex
управляет порядком обхода элементов:
tabindex="0" — элемент участвует в естественной
последовательности табуляции.tabindex="-1" — элемент не доступен для табуляции, но
доступен программно через .focus().Модальные компоненты требуют особого внимания, чтобы фокус оставался внутри окна и не уходил на элементы за пределами модального слоя.
Автофокус на открытии После монтирования
модального окна первый интерактивный элемент должен получить фокус. В
SvelteKit это удобно делать через lifecycle hook
onMount:
<script>
import { onMount } from 'svelte';
let firstInput;
onMount(() => {
firstInput.focus();
});
</script>
<input bind:this={firstInput} placeholder="Имя" />Фокус-трап (focus trap) Чтобы предотвратить уход
фокуса за пределы модального окна при использовании клавиши
Tab, применяются циклические обходы элементов. В SvelteKit
можно реализовать через массив интерактивных элементов и события
keydown:
<script>
import { onMount } from 'svelte';
let modalEl;
let focusableEls = [];
onMount(() => {
focusableEls = modalEl.querySelectorAll('button, [tabindex="0"], input, select, textarea');
});
function trapFocus(event) {
const firstEl = focusableEls[0];
const lastEl = focusableEls[focusableEls.length - 1];
if (event.key === 'Tab') {
if (event.shiftKey && document.activeElement === firstEl) {
event.preventDefault();
lastEl.focus();
} else if (!event.shiftKey && document.activeElement === lastEl) {
event.preventDefault();
firstEl.focus();
}
}
}
</script>
<div bind:this={modalEl} on:keydown={trapFocus} tabindex="-1">
<input placeholder="Имя" />
<button>Сохранить</button>
</div>При динамическом добавлении или удалении элементов важно сохранять предсказуемое поведение фокуса:
Добавление элемента — фокус может автоматически переходить на новый элемент:
<script>
let items = ['Элемент 1', 'Элемент 2'];
function addItem() {
items = [...items, `Элемент ${items.length + 1}`];
// задержка для рендера
tick().then(() => {
document.querySelectorAll('li')[items.length - 1].focus();
});
}
import { tick } from 'svelte';
</script>
<ul>
{#each items as item}
<li tabindex="0">{item}</li>
{/each}
</ul>
<button on:click={addItem}>Добавить элемент</button>Удаление элемента — фокус следует возвращать на ближайший предыдущий элемент или на родительский контейнер.
Многие UI-библиотеки для SvelteKit предоставляют готовые утилиты для фокус-менеджмента:
Dialog,
Popover, Tabs имеют встроенный фокус-трап и
автопозиционирование фокуса.Ключевые моменты при использовании таких библиотек:
autofocus на нескольких элементах
одновременно.Svelte предоставляет механизм actions, позволяющий оборачивать логику фокуса в переиспользуемый модуль:
<script>
export function autoFocus(node) {
node.focus();
return {
destroy() {}
};
}
</script>
<input use:autoFocus placeholder="Фокус автоматически" />
Этот подход позволяет централизованно управлять поведением фокуса и легко интегрировать его с UI-компонентами.
aria-* атрибуты (aria-modal,
aria-labelledby) совместно с фокус-менеджментом для
доступности.keyed each blocks.Эффективное управление фокусом делает интерфейс SvelteKit-приложений удобным для пользователей с клавиатурной навигацией, улучшает доступность и повышает качество взаимодействия с компонентами UI-библиотек.