Slim.js — это современная библиотека для создания веб-компонентов с использованием декларативных шаблонов и реактивного обновления DOM. Одним из важных аспектов разработки доступных интерфейсов является корректное использование ARIA-атрибутов. ARIA (Accessible Rich Internet Applications) позволяет сделать динамические веб-компоненты доступными для пользователей с ограниченными возможностями.
В Slim.js ARIA-атрибуты интегрируются прямо в шаблон компонентов, сохраняя реактивность и синтаксическую чистоту кода.
В Slim.js атрибуты добавляются аналогично стандартным HTML-атрибутам.
Для динамических значений используется реактивная привязка через
${}.
import { Slim } from 'slim-js';
class AccessibleButton extends Slim {
constructor() {
super();
this.ariaPressed = false;
}
toggle() {
this.ariaPressed = !this.ariaPressed;
}
get template() {
return Slim.html`
<button
@click="${this.toggle}"
aria-pressed="${this.ariaPressed}"
aria-label="Переключаемая кнопка">
Нажми меня
</button>
`;
}
}
customElements.define('accessible-button', AccessibleButton);
Ключевые моменты:
aria-pressed динамически обновляется при изменении
свойства ariaPressed.${} позволяет полностью использовать
реактивную систему Slim.js.aria-hidden,
aria-expanded, aria-labelledby и
aria-describedby, работают аналогично.Slim.js поддерживает условное отображение атрибутов. Это удобно для элементов, которые могут менять состояние.
class AccordionItem extends Slim {
constructor() {
super();
this.open = false;
}
toggle() {
this.open = !this.open;
}
get template() {
return Slim.html`
<div class="accordion-item">
<button
@click="${this.toggle}"
aria-expanded="${this.open}"
aria-controls="content">
Заголовок
</button>
<div id="content" ?hidden="${!this.open}" aria-hidden="${!this.open}">
Контент аккордеона
</div>
</div>
`;
}
}
customElements.define('accordion-item', AccordionItem);
Особенности:
aria-expanded отражает текущее состояние
компонента.aria-hidden используется для скрытия контента
от вспомогательных технологий.?hidden позволяет Slim.js управлять атрибутом
hidden в зависимости от логики состояния.Slim.js позволяет связывать свойства компонента с ARIA-атрибутами без прямой работы с DOM. Любое изменение свойства автоматически обновляет соответствующий атрибут.
class ModalDialog extends Slim {
constructor() {
super();
this.open = false;
}
openDialog() {
this.open = true;
}
closeDialog() {
this.open = false;
}
get template() {
return Slim.html`
<div
role="dialog"
aria-modal="true"
?hidden="${!this.open}"
aria-labelledby="modal-title">
<h2 id="modal-title">Диалоговое окно</h2>
<p>Контент модального окна</p>
<button @click="${this.closeDialog}">Закрыть</button>
</div>
`;
}
}
customElements.define('modal-dialog', ModalDialog);
Преимущества:
role="dialog", aria-modal,
aria-labelledby).Всегда задавать role для сложных
элементов Компоненты, имитирующие элементы интерфейса
(аккордеоны, вкладки, модальные окна), должны иметь корректный ARIA-роль
(role="tab", role="dialog",
role="menu").
Использовать динамическое обновление атрибутов
Атрибуты aria-expanded, aria-pressed,
aria-hidden должны отражать текущее состояние компонента,
иначе доступность будет нарушена.
Применять уникальные идентификаторы Для
aria-labelledby и aria-describedby
рекомендуется использовать уникальные id для связывания
элементов.
Сохранять реактивность Slim.js Не следует
напрямую изменять DOM-атрибуты через setAttribute;
предпочтительнее привязка к свойствам и использование
${}.
Тестировать с вспомогательными технологиями Проверка с экранными читалками и инструментами для оценки доступности помогает выявить пропущенные ARIA-атрибуты и некорректное состояние элементов.
Slim.js допускает использование любых нестандартных атрибутов, что позволяет расширять доступность кастомных компонентов:
class CustomToggle extends Slim {
constructor() {
super();
this.active = false;
}
toggle() {
this.active = !this.active;
}
get template() {
return Slim.html`
<div
role="switch"
@click="${this.toggle}"
aria-checked="${this.active}"
aria-description="Включение или выключение функции">
${this.active ? 'Включено' : 'Выключено'}
</div>
`;
}
}
customElements.define('custom-toggle', CustomToggle);
role="switch" и aria-checked позволяют
эмулировать функциональность переключателя.aria-description,
повышают информативность для пользователей вспомогательных
технологий.Для элементов с динамическим содержимым, таких как списки и таблицы, Slim.js позволяет управлять ARIA-атрибутами на уровне каждого элемента:
class TodoList extends Slim {
constructor() {
super();
this.items = [
{ text: 'Купить продукты', done: false },
{ text: 'Отправить письмо', done: true }
];
}
toggle(index) {
this.items[index].done = !this.items[index].done;
this.update();
}
get template() {
return Slim.html`
<ul role="list">
${this.items.map((item, i) => Slim.html`
<li role="listitem">
<input
type="checkbox"
@change="${() => this.toggle(i)}"
aria-checked="${item.done}"
?checked="${item.done}">
${item.text}
</li>
`)}
</ul>
`;
}
}
customElements.define('todo-list', TodoList);
role="listitem".aria-checked синхронизирован с состоянием
чекбокса.Использование ARIA-атрибутов в Slim.js обеспечивает совместимость с экранными читалками, улучшает доступность динамических компонентов и сохраняет чистоту кода. Правильная привязка свойств к атрибутам позволяет создавать полностью реактивные, доступные интерфейсы без лишней сложности.