Семантика разметки в Awesomplete строится вокруг идеи максимально чистой и предсказуемой структуры DOM, где автодополнение опирается не на сложные абстракции, а на стандартные HTML-элементы, дополненные минимальным набором ARIA-атрибутов для обеспечения доступности.
Основной контейнер списка предложений формируется как элемент
<ul>, внутри которого каждый вариант представлен
через <li>. Такая структура не является случайной:
она напрямую соответствует ожиданиям вспомогательных технологий, таких
как скринридеры, и обеспечивает корректную интерпретацию списка без
дополнительной логики.
Awesomplete использует предсказуемую семантику:
<div class="awesomplete">
<input id="city" autocomplete="off" />
<ul>
<li>Almaty</li>
<li>Astana</li>
<li>Karaganda</li>
</ul>
</div>
На уровне HTML это уже рабочая модель списка, однако библиотека динамически управляет его состоянием: скрывает, показывает, обновляет и синхронизирует с пользовательским вводом.
Ключевой момент заключается в том, что список не превращается в
кастомный non-semantic контейнер вроде
<div>-структур. Это снижает когнитивную нагрузку для
браузера и вспомогательных технологий.
Для корректной работы с доступностью Awesomplete дополняет базовую разметку атрибутами ARIA. Основные из них:
role="combobox" — обозначает поле ввода с
автодополнениемaria-autocomplete="list" — указывает, что подсказки
представлены спискомaria-expanded — отражает состояние раскрытия
спискаaria-owns — связывает input и список предложенийaria-activedescendant — указывает на активный элемент
спискаПример связки:
<input
id="city"
role="combobox"
aria-autocomplete="list"
aria-expanded="false"
aria-owns="awesomplete_list_1"
/>
<ul id="awesomplete_list_1" role="listbox">
<li id="awesomplete_option_1">Almaty</li>
<li id="awesomplete_option_2">Astana</li>
</ul>
Такая модель обеспечивает навигацию по списку без необходимости фокусироваться на каждом элементе мышью. Скринридер получает полное представление о структуре и состоянии компонента.
Связка между полем ввода и списком предложений является центральным элементом семантики.
Awesomplete динамически формирует идентификаторы и синхронизирует их
через aria-owns. Это позволяет экранным читалкам
воспринимать список как продолжение input-элемента.
<input aria-owns="awesomplete_list_42" />
<ul id="awesomplete_list_42"></ul>
Любое изменение списка отражается не только визуально, но и на уровне доступности. Это критически важно для корректного взаимодействия с клавиатурой и ассистивными технологиями.
Вся структура списка реализует паттерн listbox, который
является частью WAI-ARIA Authoring Practices.
<ul role="listbox">
<li role="option">Option 1</li>
</ul>
Awesomplete использует этот паттерн как основу, но оптимизирует его
под динамическое обновление. Каждый элемент списка получает роль
option, что делает его интерпретируемым как выбираемый
элемент.
<li role="option" aria-selected="true">Astana</li>
Состояние выбора отражается через aria-selected, что
позволяет скринридерам озвучивать текущий активный элемент без
визуального контакта.
Семантическая корректность списка напрямую зависит от
aria-activedescendant. Вместо постоянного перемещения
фокуса по <li> используется единый фокус на input, а
активный элемент обозначается атрибутом.
<input aria-activedescendant="awesomplete_option_2" />
Такой подход решает сразу несколько проблем:
Активный элемент визуально подсвечивается, но семантически остаётся частью списка, а не отдельным фокусируемым узлом.
Семантическое поведение списка дополняется состоянием видимости через
aria-expanded.
<input aria-expanded="false" />
При открытии списка значение изменяется:
<input aria-expanded="true" />
Это позволяет вспомогательным технологиям понимать, что интерфейс изменил состояние, даже если визуально изменение минимально.
Сам список при этом часто управляется через CSS:
.awesomplete ul {
display: none;
}
.awesomplete ul[hidden] {
display: none;
}
.awesomplete.open ul {
display: block;
}
Важно, что семантика не нарушается: скрытие не удаляет элементы из DOM, а лишь меняет их доступность.
Одной из ключевых идей Awesomplete является отказ от избыточной кастомной разметки. Не используются сложные вложенные контейнеры, декоративные div-структуры или искусственные роли.
Вместо этого сохраняется:
<input> как точка ввода<ul> как контейнер списка<li> как элемент выбораТакой подход снижает вероятность конфликтов с браузерной семантикой и улучшает предсказуемость поведения.
При обновлении списка Awesomplete пересоздаёт элементы
<li> на основе входных данных. Семантическая
структура при этом сохраняется неизменной.
list.innerHTML = "";
items.forEach((item, index) => {
const li = document.createElement("li");
li.textContent = item.label;
li.setAttribute("role", "option");
li.id = `awesomplete_option_${index}`;
list.appendChild(li);
});
Ключевой момент — каждый новый элемент сразу получает корректную ARIA-разметку, а не добавляется «пустым» с последующей модификацией.
Выбранный элемент обозначается одновременно визуально и семантически:
<li role="option" aria-selected="true">Karaganda</li>
Смена выбора приводит к строгому обновлению состояния:
aria-selected="false"aria-selected="true"Такая модель исключает неоднозначность в интерпретации состояния списка.
Семантика также включает состояние пустого списка. В Awesomplete оно
обычно отражается через отсутствие <li> элементов или
скрытие списка.
Дополнительно может использоваться ARIA-индикатор:
<ul aria-label="No results found"></ul>
или динамическое сообщение:
<div role="status">No results</div>
Это важно для того, чтобы пользовательские агенты могли корректно сообщать об отсутствии совпадений.
Awesomplete всегда существует в контексте формы, поэтому семантика input остаётся первичной. Автодополнение не заменяет поле ввода, а расширяет его поведение.
<form>
<label for="city">City</label>
<input id="city" role="combobox" />
</form>
Связь через <label> усиливает доступность, так как
позволяет однозначно интерпретировать назначение поля.
Одной из особенностей архитектуры Awesomplete является синхронизация DOM с внутренним состоянием без расхождения между визуальной и семантической моделью.
Любое изменение:
немедленно отражается в:
aria-expandedaria-activedescendantaria-selected<ul>/<li>Эта согласованность является основой корректной работы автодополнения в контексте доступного интерфейса.