TGViewer
<divelopers> <divelopers> @alexnozer_dev · 1.18K subscribers
Post #20 199
Новый элемент <selectmenu>

OpenUI разрабатывает новый элемент - <selectmenu>. Он уже более года доступен в Chrome за флагом. Этот элемент должен решить давнюю проблему - невозможность кастомизации нативного <select>.

<selectmenu>
<button
slot="button"
behavior="button"
>
<span
behavior="selected-value"
></span>
</button>
<option>Option 1</option>
<option>Option 2</option>
</selectmenu>


В чем проблема? Есть нативный <select>, который из коробки доступен, работает с формами и т.д. Но поповер с опциями никак не может быть стилизован, потому что находится на уровне ОС и недоступен для CSS. Да и внешняя часть имеет ограничения стилизации. Это приводит к тому, что вместо нативного <select> используются библиотеки, которые можно подогнать под дизайн и сделать консистентно во всех браузерах. Но это лишний js на клиенте, а во многих решениях доступность вообще не проработана. <selectmenu> - это решение. Это встроенный веб-компонент, который использует Shadow DOM для инкапсуляции разметки и логики внутри себя, slots для проброса произвольной разметки в определённые места и CSS Shadow Parts для стилизации некоторых внутренних частей.

У <selectmenu> есть определённая анатомия. Компонент состоит из кнопки, внутри которой элемент с текстом выбранной опции и иконка-треугольник. За кнопкой располагается поповер, куда попадают опции и который рисуется при открытии селекта. По умолчанию <selectmenu> работает как <select>, а именно служит контейнером для элементов <option>, которые могут быть опционально обернуты в <optgroup>.

<selectmenu>
<option>Опция 1</option>
<option>Опция 2</option>
<optgroup label="Группа">
<option>Опция 3</option>
<option>Опция 4</option>
</optgroup>
</selectmenu>

Благодаря механизму CSS Shadow Parts мы получаем возможность пробиться внутрь Shadow DOM и стилизовать некоторые части <selectmenu> при помощи специального селектора ::part(name), где name - название части: button, selected-value и listbox. Также доступны псевдоклассы :open и :closed для стилизации открытого и закрытого состояний <selectmenu> соответственно. Полезно для стилизации маркера.

selectmenu::part(button) {
/* стили кнопки */
}

selectmenu::part(selected-value) {
/* стили выбранного значения */
}

selectmenu::part(listbox) {
/* стили выпадающего списка */
}

selectmenu:open {
/* стили при открытом выпадающем списке */
}

selectmenu:closed {
/* стили при закрытом выпадающем списке */
}

Можно передавать свою разметку, используя слоты. Доступные слоты: button, selected-value, marker и listbox. Браузер заменит стандартную разметку на ту, что была передана в слот. Атрибут behavior сообщает браузеру поведение, которое нужно добавить элементу. Внутри <option> также можно разместить дополнительную разметку, что позволяет добавить иконки, картинки, многострочный текст и все это стилизовать как нужно.

<selectmenu>
<div slot="button">
<svg><!-- ... --></svg>
<button
behavior="button"
></button>
</div>
<option>
<svg><!-- ... --></svg>
<span>Опция 3</span>
</option>
<option>
<svg><!-- ... --></svg>
<span>Опция 4</span>
</option>
</selectmenu>

В слот listbox можно передать разметку, которая будет использоваться как контейнер для опций. В таком случае нужно указать атрибуты behavior="listbox" и popover="auto" (да, тут используется Popover API). Можно сделать селектор цветов как в MS Word.

Когда эту фичу раскатят - не ясно. Поэтому к релизу синтаксис может немного измениться, но слоты и части останутся в таком виде, поскольку это часть стандарта веб-компонентов. Больше примеров и подробное описание можно найти в предложении OpenUI.

UPD: компонент переименовали в <selectlist>, чтобы не было путаницы с элементом <menu> и паттерном меню.

UPD2: компонент слегка переделали, заменив селектор ::part() на псевдоклассы, а также добавив новые вспомогательные элементы <listbox> и <selectedoption>. Работа активно идёт.
  • ❤ 4
  • 👍 4
  • 🔥 4
More from @alexnozer_dev
  1. Sep 21, 2026Реализация пользовательских атрибутов Под конец прошлого года я рассказывал об API пользов…
  2. Sep 14, 2026Подклассы Event вместо CustomEvent Многие библиотеки предоставляют систему событий в качес…
  3. Sep 11, 2026Эволюция стилей в темах Shopify Адам Ватан на днях поделился новостью, что Shopify выкупил…
  4. Sep 9, 2026Persistent Widgets Многие сайты не должны быть SPA. Но иногда эта архитектура продиктована…
  5. Sep 7, 2026Processing Instructions и маркеры В DOM всё представлено в виде узлов (Node) разных типов.…
  6. Sep 1, 2026@scope и потоковая передача HTML Ноам Розенталь поделился интересной техникой, в которой с…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →