Сегодня я хочу рассмотреть предложенную функцию HTML, которая может в итоге заменить множество пользовательских компонентов ввода на основе <div>
: <selectmenu>
.
CSS это круто
Позвольте мне начать с CSS. CSS — это фантастика, потому что уже более 25 лет он позволяет нам решать, как должны выглядеть наши веб-сайты. Но так было не всегда. До появления CSS вы могли определять только структуру своих страниц, а браузеры определяли их внешний вид.
Перенесемся в настоящее, CSS не просто существует, он стал чрезвычайно универсальным. У нас есть grid’ы, CSS-переменные, преобразования через transform и многое другое, и все это довольно хорошо работает в разных браузерах. Основной принцип CSS остается неизменным: стили — это подсказки. То, как выглядят веб-сайты, зависит от предпочтений пользователей, браузеров и веб-разработчиков.
Но, возможно, в вашей дизайн-системе ваш select имеет очень специфические стили. Тени вокруг списка, особые настройки отступов… или ваш select содержит больше, чем просто строки текста, например флаги с названиями стран или аватары с именами пользователей. Элемент <select>
не позволит вам сделать всё это на CSS. Здесь на сцене появляется <selectmenu>
.
Части selectmenu
Элемент <selectmenu>
— это новый элемент HTML, предложенный Open UI Community Group. Он еще не попал в спецификацию HTML, но его прототип находится в Chromium. Вы можете проверить это, включив флаг «Experimental Web Platform Features» (перейдите на страницу about:flags и найдите этот флаг).
Когда вы используете <selectmenu>
, вы обнаружите, что оно состоит из разных частей:
<select>
- корневой элемент
<button>
— кнопка, нажав на которую, вы откроете select
<selected-value>
- текущее выбранное значение
<marker>
- стрелка, которая находится в кнопке
<listbox>
- всплывающее окно, которое открывается при нажатии на кнопку
<option>
— параметры в списке (как и в обычном <select>
)
<optgroup>
— необязательный способ группировки опций (как и в обычном <select>
)
Источник: Anatomy of the selectmenu
Стилизация selectmenu
Стилизация частей
В CSS Shadow Parts 1, который в настоящее время находится в стадии рабочего черновика (Working Draft) (т. е. еще не является полноценным стандартом), вводится новый псевдоэлемент, позволяющий стилизовать части теневых корней: ::part()
.
Подождите, разве Shadow DOM не был чем-то специфичным для веб-компонентов? Да. Но то, как <selectmenu>
реализован в браузере, похоже на веб-компонент. Вы можете смотреть на него как на веб-компонент, который поставляется с браузером.
С помощью ::part
вы можете стилизовать различные части так, как они описаны выше, например, чтобы стилизовать список, вы должны написать:
selectmenu::part(listbox) {
box-shadow: 3px 3px 3px 3px hotpink;
}
Или, может быть, вы хотите изменить внешний вид стрелки:
selectmenu::part(marker) {
box-shadow: 3px 3px 3px 3px hotpink;
}
(<marker>
еще не добавлен в объяснение selectmenu, но это было утверждено на собрании Open UI)
Состояние стилей
Вы также сможете стилизовать selectmenu в зависимости от того, открыто оно или закрыто, используя псевдокласс :open
:
selectmenu {
border: 2px solid black;
}
selectmenu:open {
border-color: hotpink;
}
Или, может быть, вам нужен другой маркер, когда selectmenu открыто:
selectmenu::part(marker) {
// regular
}
selectmenu::part(marker):open {
// open
}
Также будет псевдокласс :closed
для стилизации закрытого состояния. Это было бы эквивалентно :not(:open)
. Псевдоклассы:open
и :closed
определены в Element Display State section of Selectors, Level 4.
Кастомизация, выходящая за рамки простых стилей
Вы также можете заменить части, показанные выше, на свою собственную разметку. Части, показанные выше, представлены как «слоты», что означает, что вы можете добавить свою собственную древовидную структуру в разметку и использовать её для замены какой-либо части.
Например, вот как вы замените иконку чем-то другим:
<selectmenu>
<div slot="marker">
<!-- your own selectmenu open icon goes here -->
</div>
</selectmenu>
Все, что находится внутри этого div
будет использовано вместо стандартной иконки на кнопке, чтобы открыть selectmenu.
В принципе, <selectmenu>
позволит вам делать подобные вещи с каждой из частей, чтобы вы могли заменить кнопку или опции. Это дает разработчикам большую власть, а вместе с ней и ответственность. Итак, предостережение: вложение неправильных элементов в части selectmenu, может быстро привести к «HTMHell». Например, что, если вы поместите в опцию больше, чем просто текст — скажем, аватары — но браузеры и вспомогательные технологии ожидают только текст? Или что, если вы поместите кнопку в опцию? Подобные вложенные интерактивные элементы рискуют нарушить работу конечных пользователей в случаях, когда браузер или вспомогательные технологии не смогут волшебным образом исправить это, поэтому будьте осторожны.
Текущий статус
В настоящее время selectmenu находится в стадии «инкубации» в Open UI Community Group и разрабатывается в Chromium за флагом.
А что насчет других браузеров и браузерных движков? Я не уверен, что произойдет в Safari или Webkit, но люди из Firefox (Mozilla) присоединяются к призывам Open UI. Цитата из «The Declarative Web» посвящённая видению компании Mozilla открытости веба:
[в Интернете встроенные элементы управления] часто недостаточно оформлены и имеют несовместимую внутреннюю структуру в разных браузерах, что затрудняет их визуальное согласование с остальной частью веб-страницы. Мы хотим заполнить эти пробелы и рады видеть, что, благодаря стараниям OpenUI, уже есть успехи в этой области.
Чтобы <selectmenu>
стало реальностью, ему нужно будет перейти к стандартам, а затем получить реализацию в браузерах. Пока сложно сказать, когда это произойдет.
Резюме
Итак, вкратце: <selectmenu>
— это новое предложение, которое добавит новый элемент управления на веб-платформу, который по умолчанию похож на <select>
, но может быть оформлен и настроен практически любым способом, который вы хотите. Меня особенно радует возможность использовать ::part()
для стилизации частей, и слегка беспокоит возможность полной замены частей, поскольку это может нарушить доступность, если заменить её неправильными вещами.
Вы можете поиграть с <selectmenu>
сегодня в Microsoft Edge Canary или Google Chrome Canary и сообщить о проблемах в репозитории Open UI.
Комментарии (13)
maXimus2031
25.12.2022 10:25+8добавить туда еще input:text для поиска и цены ему не будет. А то в интернете столько разных реализаций, что постоянно приходится делать свой вариант)
jershell
25.12.2022 17:55Наверное стоит уходить от тегов в развитие канвас элементов посредством wasm, а не вот это вот всё. На текущий день у альтернативного подхода есть проблемы, отсутствие людей с ограниченными возможностями и вялое развитие wasm.
alexander222
26.12.2022 00:16Вам стоит посмотреть в сторону flutter, для веба он примерно так и рендерит.
nin-jin
Прекрасно. Ждём стилизацию датепикера ещё через 10 лет.
funca
Веб всю историю пытается усидеть на трёх стульях. С одной стороны это желание дать пользователям привычный UX (что в переделе возможно лишь при использовании нативных контролов операционной системы). С другой - стилизация всего ради удовлетворения эстетических прихотей разработчиков либо их менеджеров (а значит отказ от нативных контролов в пользу самописных аналогов). И третья - не дать браузеру превратиться в полноценный кроссплатформенный UI toolkit (по типу XUL, XAML и т.п).
sshikov
Вы так говорите, как будто это что-то плохое.
Стилизация всего — дело вполне осмысленное. Иначе вы навсегда будете привязаны к тем возможностям, что имеют нативные контролы. И всегда будете ими ограничены.
То есть да, пытается. Я не вижу в этом ничего плохого. Потребности разные. Кому-то нужно первое, кому-то второе. А третье — это попытка ограничить сложность. В том числе — хорошо бы научиться наконец переиспользовать все что можно от нативных контролов, чтобы не переписывать все с нуля, а писать только и именно то, что нужно.
nin-jin
Нативные контролы не имеют смысла в кастомном дизайне. Тут надо либо контролы в дизайне сайта иметь (а натив не настолько кастомизируем), либо дизайн сайта мимикрировать под систему (а тут любой кастомный элемент страницы превращается в 100500 версий под разные системные дизайны).
sshikov
>Нативные контролы не имеют смысла в кастомном дизайне.
Так я и говорю, что не всем нужен кастомный дизайн. Иногда наоборот хочется походить на нативное приложение (и менять дизайн при изменении настроек системы). Осмысленно ли это само по себе? Наверное не всегда, но в жизни такое встречается.
funca
Скорее это что-то сложное. Написать кастомный контрол, имитирующий поведение нативных это дорого. Я имею ввиду полноценную поддержку нюансов различных устройств ввода и вывода, внутренней навигации, масштабирования и т.п. В нашем энтерпрайзе резко отказались от большинства кастомных контролов в вебе как только появились риски комплайнса по части a11y. Внезапно визуальная разница и хотелки перестали быть такой уж важной проблемой.
sshikov
А. Ну тогда я не совсем понял посыл исходного коммента.
Сложно конечно. Вот как это ни удивительно, но в моей практике писать свои контролы проще всего было для Flex (который надстройка над Flash). И вот это вот все давненько уже было — а по сути с тех пор лучше особо не стало. Дорого и сложно. И баги, зачастую самые тупые. Скажем, некий явно кастомный контрол, вроде того, что тут описан в тексте. В поле ввода не работает удаление по кнопке backspace.
> риски комплайнса по части a11y
Слишком дорого поддерживать одновременно и хотелки, и a11y?
funca
Когда вы используете стандартные контролы, то проблемы с a11y в этой части перееадресуются разработчикам браузера. Если кастомные - то это ваша ответственность (даже если вы купили библиотеку у вендора или взяли из open source). Конечно, можно делать две версии: одну соответствующую законным требованиям, а вторую - эстетическим. Но тут в дело вступают деньги.
Проблема с a11y в том, что поддержка добавляет изрядную пачку нефункциональных требований, а бардак по части браузеров и сопутствующих решений здесь как в нулевые.
sshikov
Ну да, я примерно это и предполагал.