Группа OpenUI продолжает работать над проектированием стандартных возможностей для создания пользовательских интерфейсов. Не так давно на сайте появилось новое предложение под названием Openable API.
Дисклеймер: это обзор раннего предложения новых функций. Синтаксис может измениться в будущем или от функций могут отказаться.
В интерфейсах часто встречается шаблон, когда элемент скрыт (
display: none) и появляется при нажатии кнопки. В качестве примеров виджет показать/скрыть (show/hide, disclosure), древовидный раскрываемый список (tree) или раскрываемые строки таблиц.Суть таких виджетов можно описать следующим примером кода:
<button
type="button"
aria-expanded="false"
aria-controls="details"
>
Подробнее
</button>
<div
id="details"
role="group"
hidden
>
Скрытый контент
</div>
<script>
const button = document.querySelector('button');
const details = document.querySelector('#details');
button.addEventListener('click', () => {
details.hidden = !details.hidden;
button.setAttribute(
'aria-expanded',
String(!details.hidden)
);
});
</script>
То есть скрыть контент, найти элемент-триггер, найти скрытый контент, при нажатии на триггер показать контент, при повторном нажатии скрыть контент. Openable API призван добавить в браузеры примитив для создания подобных виджетов.
Предлагается новый глобальный атрибут
openable. Он делает элемент скрытым по умолчанию, добавляет ему JS-методы openOpenable(), closeOpenable() и toggleOpenable() для программного переключения видимости. Похоже на Popover API.<button type="button">
Подробнее
</button>
<div role="group" openable>
Скрытый контент
</div>
<script>
const button = document.querySelector('button');
const details = document.querySelector('[openable]');
button.addEventListener('click', () => {
details.toggleOpenable();
});
</script>
Чтобы элемент по умолчанию был виден, предлагается ещё один атрибут —
defaultopen, который связан со свойством элемента defaultOpen. Установка этого атрибута на элемент или изменение значения свойства на true приводит к переключению.Вместе с JS-методами предлагается декларативный способ переключения с использованием Command Invokers, о которых я рассказывал. К ним добавляются новые системные команды, что позволяет делать переключение без JS:
<button
type="button"
commandfor="details"
command="toggle-openable"
>
Подробнее
</button>
<div id="details" openable>
Скрытый контент
</div>
Для стилизации предусмотрен псевдо-класс
:open, который соответствует элементу в раскрытом состоянии. С псевдо-классом :not() можно будет стилизовать скрытое состояние. Браузеры должны применять следующие системные стили:[openable]:not([hidden=until-found]):not(:open) {
display: none;
}
[openable][hidden=until-found]:open {
content-visibility: revert;
}Для отслеживания переключения в JS предлагаются события
toggle и beforetoggle, как у <dialog> и Popover API. Предусмотрен возврат фокуса при закрытии.Подумали о поиске на странице, чтобы скрытый контент отображался, если соответствует искомой фразе. Подумали о доступности. Хотя предложение всё ещё находится в стадии раннего черновика.
Для декларативного переключения видимости есть элементы
<details>/<summary>, <dialog> и Popover API. Зачем нужен ещё один способ?- У
<details>/<summary> есть встроенная семантика и ограничения по структуре;- У
<dialog> также есть чёткая семантика и поведение вокруг модальности, фокуса, способа закрытия и отображения поверх страницы;- С Popover API ситуация как у
<dialog>, кроме того, что поповером может быть любой элемент.Openable API применяется к любым (с оговорками) элементам, не добавляет семантику, не отображается поверх другого контента, не вносит сложную модель фокус-менеджмента.
Посмотрим, куда будет двигаться это предложение. Идея в целом классная и полезная. Чем больше будет API с поддержкой декларативности, где браузер забирает на себя часть логики, тем проще и доступнее будет создание интерфейсов.
#html #css #js #ui