I wish to introduce you to a brand new, experimental type management referred to as <selectmenu>
. We’ll get deep into it, together with how a lot simpler it’s to fashion than a standard <choose>
component. However first, let’s fill in some context about why one thing like <selectmenu>
is required within the first place, because it’s nonetheless evolving and in improvement.

Ask any internet developer what they suppose is lacking from the net platform as we speak, likelihood is the power to fashion type controls shall be on their checklist. In truth, type styling was voted as one of many top-10 lacking issues within the State of CSS Survey in 2020. It was then additional surveyed by Greg Whitworth who showed that <choose>
was the management internet builders have been having essentially the most issues styling with CSS.
Whereas it’s comparatively straightforward to fashion the looks of the button a part of a <choose>
(the factor you see within the web page when the popup is closed), it’s nearly unattainable to fashion the choices (the factor you see when the popup is open), not to mention add extra content material throughout the popup.

<choose>
component in SafariIn consequence, design programs and element libraries have been rolling out their very own selects, constructed from scratch utilizing {custom} HTML markup, CSS, and sometimes numerous JavaScript, in an effort to have one thing that integrates properly with the opposite parts.
Sadly, doing so accurately with the appropriate accessibility semantics, keyboard help, and popup positioning just isn’t straightforward. Internet builders have poured hours and hours over time, attempting to resolve the identical issues time and again, and there are lots of inaccessible selects on the market.
It’s about time we obtained a correctly style-able built-in <choose>
so we don’t have to put in writing this code ever once more!
The Open UI initiative

Open UI is a gaggle of builders, designers, and browser implementers who got down to resolve this precise downside, and whereas they’re at it, sort out different lacking controls too.
The aim of Open UI is to finally make it doable for internet builders to fashion and lengthen built-in UI controls (this contains <choose>, however dropdowns, checkboxes, radio buttons, and others too). To realize this, they produce specs for a way these controls needs to be carried out within the internet platform in addition to the accessibility necessities they need to tackle.
The venture remains to be in its infancy, however issues are shifting quick and, as we’ll see beneath, thrilling issues are already taking place.
You’ll be able to be a part of the group and take part within the conferences, analysis, and specification efforts.
Based mostly on the Open UI’s <select>
proposal, the implementation of a brand new <selectmenu>
management has began in Chromium! The work is finished by the Microsoft Edge staff, in collaboration with the Google Chrome staff. It’s even already out there in Chromium-based browsers by enabling the “Experimental Internet Platform options” flag within the about:flags web page
.
<selectmenu>
is a brand new built-in management that gives an possibility choice consumer expertise, similar to <choose>
, with a button displaying the chosen worth label, a popup that seems when that button is clicked, and an inventory of choices that get displayed.
Why a brand new title?
Why not simply change the prevailing <choose>
management? The title “selectmenu” began as a working title, but it surely appears to have caught to date, and nobody has provide you with something higher but.
Extra importantly, the prevailing <choose>
management has been used on the internet for a really very long time. As such, it might most likely by no means be modified in any important manner with out inflicting main compatibility points.
So, the plan (and keep in mind that is all nonetheless very experimental) is for <selectmenu>
to be a brand new management, unbiased from <choose>
.
Strive it out as we speak
This isn’t prepared for manufacturing use but, however in the event you’re as excited as I’m about utilizing it, right here’s how:
- Open a Canary model of a Chromium-based browser (Chrome, Edge).
- Change the “Experimental Internet Platform options” flag within the
about:flags
web page and restart. - Exchange any
<choose>
by<selectmenu>
in an internet web page!
That’s it! It received’t do a lot by default, however as we’ll see later, you’ll be capable to fashion and lengthen the management fairly extensively with this one tag title change.
We love suggestions!
Earlier than we go into the way to use the management, in the event you do use it, the Open UI group and other people engaged on the implementation in Chromium would love to listen to your suggestions you probably have any.
By being an early tester, you possibly can actively assist them make the management higher for everybody. So, in the event you encounter bugs or limitations with the design of the management, please ship your suggestions by creating an issue on the Open UI GitHub repository!
And now, let’s speak about how the management works.
As a result of the varied elements of the selectmenu may be styled, it’s vital to first perceive its inside anatomy.

<selectmenu>
is the foundation component that accommodates the button and listbox.<button>
is the component that triggers the visibility of the listbox.<selected-value>
is the component that shows the worth of the at the moment choice possibility (elective). Observe that this half doesn’t essentially should be positioned contained in the<button>
half.<listbox>
is the wrapper that accommodates the<possibility>
s and<optgroup>
s.<optgroup>
teams s along with an elective label.<possibility>
represents the potential worth that may be chosen by the consumer. There may be a number of.
Default habits
The default habits of the <selectmenu>
management mimics the habits of the <choose>
management. You need to use it similar to a local <choose>
, with the next minimal markup.
<selectmenu>
<possibility>Choice 1</possibility>
<possibility>Choice 2</possibility>
<possibility>Choice 3</possibility>
</selectmenu>
When doing so, the default <button>
, <selected-value>
, and <listbox
>are created for you.
Styling elements of the management
That is the place issues turn out to be fascinating! One solution to fashion the management to match your necessities is to make use of the CSS ::part()
pseudo-element to pick out the completely different elements throughout the management’s anatomy that you simply want to fashion.
Take into account the next instance the place ::half()
is used to fashion the button and the listbox elements:
<fashion>
.my-select-menu::half(button) {
colour: white;
background-color: #f00;
padding: 5px;
border-radius: 5px;
}
.my-select-menu::half(listbox) {
padding: 10px;
margin-top: 5px;
border: 1px stable crimson;
border-radius: 5px;
}
</fashion>
<selectmenu class="my-select-menu">
<possibility>Choice 1</possibility>
<possibility>Choice 2</possibility>
<possibility>Choice 3</possibility>
</selectmenu>
The above instance ends in the next fashion:

::half()
can be utilized to fashion the <button>
, <selected-value>
, and <listbox>
elements of the management.
Use your personal markup
If the above isn’t sufficient on your wants, you possibly can customise the management rather more by offering your personal markup to switch the default one, and lengthen or re-order the elements.
A <selectmenu>
has named slots that may be referenced to switch the default elements. For instance, to switch the default button with your personal, you are able to do the next:
<fashion>
.my-custom-select [slot="button"] {
show: flex;
align-content: heart;
}
.my-custom-select button {
padding: 5px;
border: none;
background: #f06;
border-radius: 5px 0 0 5px;
colour: white;
font-weight: daring;
}
.my-custom-select .label {
padding: 5px;
border: 1px stable #f06;
border-radius: 0 5px 5px 0;
}
</fashion>
<selectmenu class="my-custom-select">
<div slot="button">
<button habits="button">Open</button>
<span class="label">Select an possibility</span>
</div>
<possibility>Choice 1</possibility>
<possibility>Choice 2</possibility>
<possibility>Choice 3</possibility>
</selectmenu>
The slot="button"
attribute on the outer <div>
tells the <selectmenu>
to switch its default button with the contents of the <div>
.
The habits="button"
attribute on the internal <button>
tells the browser that this component is what we wish to use as the brand new button. The browser will mechanically apply all the press and keyboard dealing with habits to this component in addition to the suitable accessibility semantics.
The above code snippet ends in the next fashion:

Observe that the slot
and habits
attributes can be used on the identical component.
You’ll be able to change the default listbox half similarly:
<fashion>
.my-custom-select popup {
width: 300px;
show: grid;
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
hole: 10px;
padding: 10px;
box-shadow: none;
margin: 10px 0;
border: 1px stable;
background: #f7f7f7;
}
</fashion>
<selectmenu class="my-custom-select">
<div slot="listbox">
<popup habits="listbox">
<possibility>Choice 1</possibility>
<possibility>Choice 2</possibility>
<possibility>Choice 3</possibility>
<possibility>Choice 4</possibility>
<possibility>Choice 5</possibility>
</popup>
</div>
</selectmenu>
Apparently, the <popup>
used right here can be being proposed by Open UI and carried out in Chromium in the mean time.
The component with habits="listbox"
is required to be a <popup>
. Making use of habits="listbox"
tells the browser to open this component when the <selectmenu>
button is clicked, and the consumer can choose <possibility>
s inside it with mouse, arrow keys, and contact.
The above code snippet ends in the next fashion:

Extending the markup
Not solely are you able to change the default elements with your personal, as seen above, it’s also possible to lengthen the management’s markup by including new components. This may be helpful to enhance the listbox or button with additional info, or so as to add new performance.
Take into account the next instance:
<fashion>
.my-custom-select [slot="button"] {
show: flex;
align-items: heart;
hole: 1rem;
}
.my-custom-select button {
border: none;
margin: 0;
padding: 0;
width: 2rem;
peak: 2rem;
border-radius: 50%;
show: grid;
place-content: heart;
}
.my-custom-select button::earlier than {
content material: '25BC';
}
.my-custom-select popup {
padding: 0;
}
.my-custom-select .part {
padding: 1rem 0 0;
background: radial-gradient(ellipse 60% 50px at heart prime, #000a 0%, clear 130%);
}
.my-custom-select h3 {
margin: 0 0 1rem 0;
text-align: heart;
colour: white;
}
.my-custom-select possibility {
text-align: heart;
padding: 0.5rem;
}
</fashion>
<selectmenu class="my-custom-select">
<div slot="button">
<span class="label">Select a plant</span>
<span habits="selected-value" slot="selected-value"></span>
<button habits="button"></button>
</div>
<div slot="listbox">
<popup habits="listbox">
<div class="part">
<h3>Flowers</h3>
<possibility>Rose</possibility>
<possibility>Lily</possibility>
<possibility>Orchid</possibility>
<possibility>Tulip</possibility>
</div>
<div class="part">
<h3>Bushes</h3>
<possibility>Weeping willow</possibility>
<possibility>Dragon tree</possibility>
<possibility>Big sequoia</possibility>
</div>
</popup>
</div>
</selectmenu>
Right here we’re utilizing {custom} markup to wrap the checklist of choices and create our personal content material as seen beneath:

Changing your complete shadow DOM
Lastly, and if the above wasn’t sufficient, it’s also possible to lengthen the management’s markup by changing its default shadow DOM altogether by calling attachShadow()
. For instance, the demo within the previous section may very well be modified as follows:
<selectmenu id="my-custom-select"></selectmenu>
<script>
const myCustomSelect = doc.querySelector('#my-custom-select')
const shadow = myCustomSelect.attachShadow({ mode: 'closed' })
shadow.innerHTML = `
<fashion>
.button-container {
show: flex;
align-items: heart;
hole: 1rem;
}
button {
border: none;
margin: 0;
padding: 0;
width: 2rem;
peak: 2rem;
border-radius: 50%;
show: grid;
place-content: heart;
}
button::earlier than {
content material: '025BC';
}
popup {
padding: 0;
}
.part {
padding: 1rem 0 0;
background: radial-gradient(ellipse 60% 50px at heart prime, #000a 0%, clear 130%);
}
h3 {
margin: 0 0 1rem 0;
text-align: heart;
colour: white;
}
possibility {
text-align: heart;
padding: 0.5rem;
}
possibility:hover {
background-color: lightgrey;
}
</fashion>
<div class="button-container">
<span class="label">Select a plant</span>
<span habits="selected-value" slot="selected-value"></span>
<button habits="button"></button>
</div>
<popup habits="listbox">
<div class="part">
<h3>Flowers</h3>
<possibility>Rose</possibility>
<possibility>Lily</possibility>
<possibility>Orchid</possibility>
<possibility>Tulip</possibility>
</div>
<div class="part">
<h3>Bushes</h3>
<possibility>Weeping willow</possibility>
<possibility>Dragon tree</possibility>
<possibility>Big sequoia</possibility>
</div>
</popup>
`
</script>
Written this manner, the <selectmenu>
‘s {custom} markup is absolutely encapsulated in its shadow DOM. The <selectmenu>
can subsequently be dropped into any web page with out danger of interference from the encircling content material’s types.
As we’ve seen, the brand new experimental <selectmenu>
management gives numerous flexibility in the case of styling and even extending a standard <choose>
. And it does this in all the appropriate methods, as a result of it’s constructed into the browser the place accessibility and viewport-aware positioning are dealt with for you.
Open UI has more documentation about <selectmenu>
, and if you wish to see extra code displaying the way to use the <selectmenu>
, here are a few demos as effectively.
Once more, that is work in progress and can most definitely change because of suggestions obtained by the Open UI group.
I can’t wait to see specs begin to seem in HTML and CSS commonplace our bodies, and for the implementation to turn out to be extra steady, in addition to see different browser engines getting on this. You’ll be able to assist make this occur! Testing the management, reporting issues, or getting involved are all nice methods to assist push this effort ahead.