Skip to content

Customizable <select> element #9799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
josepharhar opened this issue Sep 26, 2023 · 68 comments
Open

Customizable <select> element #9799

josepharhar opened this issue Sep 26, 2023 · 68 comments
Labels
addition/proposal New features or enhancements stage: 3 Committed topic: forms topic: parser topic: select The <select> element

Comments

@josepharhar
Copy link
Contributor

josepharhar commented Sep 26, 2023

This proposal includes parser, styling, and rendering changes to make the <select> element fully customizable by authors.

Explainer: https://open-ui.org/components/customizableselect

Spec PRs:

CSS spec PRs:

Accessibility PRs:

Related HTML issues:

Related CSS issues:

Standards positions:

@zcorpan zcorpan added addition/proposal New features or enhancements topic: forms labels Sep 27, 2023
@zcorpan
Copy link
Member

zcorpan commented Sep 27, 2023

@whatwg/forms

@mfreed7 mfreed7 added the stage: 0 Proposal label Oct 5, 2023
@rohankaushal123

This comment was marked as spam.

@annevk
Copy link
Member

annevk commented Oct 19, 2023

Thank you for bringing this proposal to the WHATWG Joey! I thought this would be a good opportunity to outline how colleagues and I feel about extending HTML in this area. In particular, we feel that new and existing form controls:

  • Should look the same as the operating system controls by default.
  • Should be fully styleable by web developers.
  • Should generally attempt to follow existing HTML element patterns.
  • Should not be redundant with existing HTML form controls.
  • Should work on a wide variety of platforms, including those with very small screens, no mouse or touch, etc.
  • Should be fully accessible.
  • Should not have any l10n or i18n shortcomings.

We understand that the select element can’t address a variety of scenarios due to parser limitations, but the select element could address them in combination with the datalist element. One of our big worries with complete duplication is that we end up not solving the problems with the existing controls and that the duplicated controls will have a variety of shortcomings the older controls did not have.

(Aside: #5791 seems very related to this issue.)

@hsivonen
Copy link
Member

I think the explainer doesn't explain the need for a new element in a convincing way, because the multiple examples look addressable in the context of select: flags are addressable by emoji instead of image files, subheadings by the label attribute of optgroup, and color and font-level styling seems feasible without a new element.

(From off-explainer examples, I gather that the ambition level of the feature is much higher than the explainer makes appear.)

@josepharhar
Copy link
Contributor Author

Thanks for taking a look and discussing with colleagues Anne!

Should look the same as the operating system controls by default.

If we made appearance:none or a new appearance value like appearance:base as discussed here and here have a standardized style, then the default appearance:auto appearance could look the same as OS controls. That would be up to each UA to decide, as it is currently for all other form controls.

Should be fully styleable by web developers.

Agreed! Styleability is the primary driving use case for the current proposal.

Should generally attempt to follow existing HTML element patterns.

Agreed! Domenic left some feedback in this vein and we completely revamped the proposal to use existing HTML element patterns by using new tag names instead of slot and behavior attributes.

Should work on a wide variety of platforms, including those with very small screens, no mouse or touch, etc.

Agreed! Existing elements conform to this by letting the browser/OS provide a native picker which unfortunately can’t be styled or customized by web developers, right? It was recommended that we let the browser use native pickers for selectlist on mobile here. Ideally developers would be enabled to make their own pickers that work on these platforms when they want to as well.

Should be fully accessible.

Agreed! This is also a core requirement for the proposal. I have been working closely with accessibility experts participating in OpenUI to ensure that the accessibility mappings and keyboard behaviors follow the current best practices in ARIA.

Should not have any l10n or i18n shortcomings.

Agreed! The content is fully customizable/replaceable, so it should be localizable and internationalizable, right? The only thing I can think of is supporting right-to-left and vertical writing modes when rendering where the listbox popup goes, which is something we are doing for other form control elements and we can easily do via Anchor Positioning for selectlist. Is there anything else you had in mind here?

Should not be redundant with existing HTML form controls.

We understand that the select element can’t address a variety of scenarios due to parser limitations, but the select element could address them in combination with the datalist element

It sounds like yall would prefer to reuse the existing <select> element instead of creating a new tag name. Am I correct? As you mentioned, we can’t have the new content model exist inside the <select> element due to parser rules, but we could try to do something with how datalist works by adding attributes to <select> which refer to the other elements we want to use, which would perhaps look like <select list=my-listbox button=my-button>. However, I don’t think this would work well. This works for <input list=datalist> because datalists are just used to host text data without doing actual rendering. Since we are actually trying to render an authored <listbox> or <button> element inside the select/selectlist, we don’t have the machinery in the browser to render them from an arbitrary location in the DOM. ShadowDOM is perfect for this and is how existing builtin elements like details and summary work. It is also easier and more idiomatic (like <option> and <summary>) for the new listbox and button elements to know when they should have special behavior for selectlist because they can look at their parent context rather than having to keep track of which select element has an attribute pointing at them. A preview of the State of HTML survey I’ve seen also lists <datalist> as a top developer pain point, which perhaps alludes that the ergonomics of referring to a separate element aren’t great.

One of our big worries with complete duplication is that we end up not solving the problems with the existing controls and that the duplicated controls will have a variety of shortcomings the older controls did not have.

I agree that duplication should be avoided. Selectlist is not a complete duplicate of select. <select> can draw outside the bounds of the browser window, and <selectlist> has a completely different rendering model that allows full customization. If it were possible to shoehorn into <select> that would be nice, but it looks infeasible.

@josepharhar
Copy link
Contributor Author

I think the explainer doesn't explain the need for a new element in a convincing way, because the multiple examples look addressable in the context of select: flags are addressable by emoji instead of image files, subheadings by the label attribute of optgroup, and color and font-level styling seems feasible without a new element.

Thanks for the feedback! I am improving the examples here: openui/open-ui#918

@lukewarlow
Copy link
Member

lukewarlow commented Oct 30, 2023

flags are addressable by emoji instead of image files

I just wanted to point out Windows doesn't provide flag emojis so this specific example is a good use case for needing images not emoji.

@annevk
Copy link
Member

annevk commented Nov 1, 2023

Existing elements conform to this by letting the browser/OS provide a native picker which unfortunately can’t be styled or customized by web developers, right?

If you use appearance:none they can usually be styled. And we should do more work here to add something akin to appearance:base to make that more ergonomic for web developers. I don't think the solution should be adding new elements that don't have platform theming by default as that would make the HTML language inconsistent.

ShadowDOM is perfect for this and is how existing builtin elements like details and summary work.

For <datalist id=options> we'd have to clone the options into the select element's shadow tree for rendering purposes, I think, much in the same way we probably have to clone one of the options as the selected option. As long as this happens in the internal shadow tree it's largely not observable and should be okay.

It would also have the benefit of having a consistent design with <input type=text list=options>, so we'd tackle combo boxes at the same time (or at least make it possible to reuse the design for them). Since the <datalist> continues to mainly serve as a source of data I don't think there's any need to track what element is pointing to it.

(There are some challenges here with how to match these options and their elements from CSS, but that seems like a surmountable problem.)

I haven't looked at survey in detail, but I'd assume that if <datalist> is mentioned as a pain point it would mainly be around not being able to style it, which is something we'd have to tackle for combo boxes and select alike.

@josepharhar
Copy link
Contributor Author

I’ve been discussing with @annevk and @pxlcoder about how to move forward here, and we have reached agreement on some things. Please correct if I misrepresent anything!

  • Reusing the <select> element will work
  • We can change the parser for <select> to allow particular new child tags like <button> and <datalist>
  • We can work incrementally, first by making these parser changes in the spec etc.
  • Using <datalist> as a child of <select> will work to replace the listbox with custom content

@lukewarlow
Copy link
Member

lukewarlow commented Dec 1, 2023

I'm concerned by the implications of the multiple attribute. How does it work with the new parsing?

That being said I am excited by the progressive enhancement possibilities.

@gregwhitworth
Copy link

If you use appearance:none they can usually be styled. And we should do more work here to add something akin to appearance:base to make that more ergonomic for web developers.

@annevk The majority you cannot and it isn't solely about styling but also extending them. While select may be able to be re-used; one of the benefits of introducing the new elements that are interoperable by default and not OS platform styled does make the platform consistent rather than trying to retro-fit all the build-in UI controls. I think we may want to fork this into a more generic issue specific to the introduction of new elements as I'm curious how your assertion holds up for input type=switch that not only allows styling but extensibility without a new element; type=file, type=progress, etc?

Using <datalist> as a child of <select> will work to replace the listbox with custom content
This makes sense to me outside of my position that we should introduce a new element, not a new CSS attribute to solve this problem as it's not just about styling

@josepharhar @annevk so will this likewise have the child of <selectedoption> and ability to modify the initial shadow DOM?

@josepharhar
Copy link
Contributor Author

@josepharhar @annevk so will this likewise have the child of <selectedoption> and ability to modify the initial shadow DOM?

The idea (as I see it) is to still have a <selectedoption> element that can be a child of the <button> element we use to replace the <select>'s default button.

The UA shadowroot will certainly adapt if and when needed to support slotting in and replacing the default button and listbox.

Does that answer your question? I'm not sure if I understood it well.

chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 18, 2023
As per the spec discussion, we are going to allow <button>s in <select>
to replace the opener button and <datalist>s in <select> to replace the
listbox instead of creating a <selectlist> element.
whatwg/html#9799

Bug: 1511354
Change-Id: If2ee766c57faf655ab31c6714be7fd682efcc177
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 19, 2023
As per the spec discussion, we are going to allow <button>s in <select>
to replace the opener button and <datalist>s in <select> to replace the
listbox instead of creating a <selectlist> element.
whatwg/html#9799

Bug: 1511354
Change-Id: If2ee766c57faf655ab31c6714be7fd682efcc177
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 19, 2023
As per the spec discussion, we are going to allow <button>s in <select>
to replace the opener button and <datalist>s in <select> to replace the
listbox instead of creating a <selectlist> element.
whatwg/html#9799

Bug: 1511354
Change-Id: If2ee766c57faf655ab31c6714be7fd682efcc177
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Dec 19, 2023
As per the spec discussion, we are going to allow <button>s in <select>
to replace the opener button and <datalist>s in <select> to replace the
listbox instead of creating a <selectlist> element.
whatwg/html#9799

Bug: 1511354
Change-Id: If2ee766c57faf655ab31c6714be7fd682efcc177
chromium-wpt-export-bot pushed a commit to web-platform-tests/wpt that referenced this issue Jan 8, 2024
As per the spec discussion, we are going to allow <button>s in <select>
to replace the opener button and <datalist>s in <select> to replace the
listbox instead of creating a <selectlist> element.
whatwg/html#9799

Bug: 1511354
Change-Id: If2ee766c57faf655ab31c6714be7fd682efcc177
@josepharhar josepharhar added the agenda+ To be discussed at a triage meeting label Jan 9, 2024
@josepharhar
Copy link
Contributor Author

Adding agenda+ to move this to stage 1

@josepharhar
Copy link
Contributor Author

I updated the explainer to be <select> instead of <selectlist>: https://open-ui.org/components/selectlist/

@keithamus keithamus added agenda+ To be discussed at a triage meeting and removed agenda+ To be discussed at a triage meeting labels Jan 11, 2024
@josepharhar josepharhar changed the title The <selectlist> element Stylable <select> element Jan 11, 2024
@josepharhar
Copy link
Contributor Author

I added accessibility related PRs to the OP

@dgrammatiko
Copy link

Will there be a polyfill?

@josepharhar
Copy link
Contributor Author

I'm not planning on creating a polyfill. Ideally, select elements in non-supporting browsers will still be perfectly usable but not have the new appearance of customizable select.

@dgrammatiko
Copy link

@josepharhar thanks, it makes sense if the browser parser will ignore any of the new relaxed allowed elements.

@starball5

This comment has been minimized.

@trans
Copy link

trans commented Apr 17, 2025

I would like to contribute my thoughts to this endeavor. I haven't been exactly sure how to go about that. So initially I wrote up a small blog post, but found no good way to share it (I had nothing but problems trying to get on matrix chat). Then I found this issue, and decided I'd just try sharing it here.

The post is not long, but for a super quick overview, I am suggesting the following:

  1. An <options> container element, instead of using a pseudo-selector (picker(select)).
  2. Use the more concise and intuitive term <selection> instead of <selectedcontent>.
  3. Allow options to be detached from the select (for e.g. modal-style UX).
  4. Not strictly about style but... support readonly and auto-selecting value attributes.

(If this would be better vetted elsewhere, please let me know. I don't have a lot of time to spare but am willing to do what I can.)

@josepharhar
Copy link
Contributor Author

  • An <options> container element, instead of using a pseudo-selector (picker(select)).

We sort of had this before as a datalist element, but we decided to remove that here: openui/open-ui#1082

  • Use the more concise and intuitive term <selection> instead of <selectedcontent>.

<selection> was one of the proposed options when we named <selectedcontent> here: openui/open-ui#1112

  • Allow options to be detached from the select (for e.g. modal-style UX).

You can already make customizable select appear like a modal by applying styles to ::picker(select) like this: https://codepen.io/jarhar/pen/NPPPrgx

Since its all in CSS, this has the added benefit of being able to change this based on media queries.

4. Not strictly about style but... support readonly and auto-selecting value attributes.

Not sure I completely understand, but if you don't want the user to change the value then you can use the disabled attribute on the select element. If you want an option to be selected by default, then you can set the selected attribute on it. Neither of these things are new with customizable select.

@JoeMurray
Copy link

tl;dr If this progresses normally, what is the likely timeline for it to be generally supported by major browsers?

An open source project I am involved with (CiviCRM) is looking for good accessible alternatives to the select2 widget that failed to be accepted into the WordPress Gutenberg editor about 6 years ago due to pushback from a11y advocates. There don't seem to be any but this initiative would be ideal. However, some of us are thinking that waiting for it is likely over-optimistic on our part. Does it stand a good chance of seeing the light of day including being implemented by all major browsers in the next few years? Hard to guess, I know, but we aren't knowledgeable about how to assess things so far upstream from our work. TIA.

@trans
Copy link

trans commented Apr 25, 2025

  • An <options> container element, instead of using a pseudo-selector (picker(select)).

We sort of had this before as a datalist element, but we decided to remove that here: openui/open-ui#1082

Well that's unfortunate -- seems datalist is getting axed across the board. From what I read the option container is now just a div (with a popover attribute).

That's what really bothers me about this, it creates a ghost div that has no explicit representation in the HTML. Notice @mfreed7 asked if we would still be able to wrap the option elements in a div in the HTML, and the answer was "yes". But I tried it on Chrome and it doesn't behave as one would expect because there is this other shadowy div in there wrapping around it. If this div is going to be in there it should be explicit -- if the HTML doesn't have it, it gets added (like e.g. tbody, etc.)

  • Use the more concise and intuitive term <selection> instead of <selectedcontent>.

<selection> was one of the proposed options when we named <selectedcontent> here: openui/open-ui#1112

So the issue is it is too reminiscent of the text selection pseudo-selector, is that it? Shrug Minor issue anyway.

I was thinking about this and I am not sure how useful <selectedcontent> will be. What scenario is common that would need this?

If I understand it correctly, it can also be emulated by putting content outside the select and styling it look like a select. With a little CSS adjustment it would look pretty much the same. Only thing that might not be easy is exact positioning (popover oddness there) and the placement of the dropdown marker icon (but I'd imagine for such uses the marker will get hidden anyway). Note, I tried it in Chrome for comparison and selectedcontent doesn't seem to be working -- it winds up the options div? (https://codepen.io/Thomas-Sawyer-the-looper/pen/ZYYyXjd)

To me, what would be much more useful is a way for options to have longer descriptions, but only a short version ends up on the select button. E.g. consider a list of states where you want the the select button to have just the two letter abbreviation but the options to also have the full name, like <option>FL - Florida</option>. How can you get just "FL" to appear on the select button?

  • Allow options to be detached from the select (for e.g. modal-style UX).

You can already make customizable select appear like a modal by applying styles to ::picker(select) like this: https://codepen.io/jarhar/pen/NPPPrgx

Since its all in CSS, this has the added benefit of being able to change this based on media queries.

That's a good point! You are right I updated my post to retract the "attachment" being based on HTML structure. I still think there option elements container needs to have an explicit manifestation in the HTML though.

  1. Not strictly about style but... support readonly and auto-selecting value attributes.

Not sure I completely understand, but if you don't want the user to change the value then you can use the disabled attribute on the select element. If you want an option to be selected by default, then you can set the selected attribute on it. Neither of these things are new with customizable select.

I'll try the disabled attribute and see how that works. Thanks. As for the selected attribute, that's actually what I don't want to have to do -- rather, if the value of select and the value of option match I want the selected attribute to be automatic -- it would simply template loops that build select elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
addition/proposal New features or enhancements stage: 3 Committed topic: forms topic: parser topic: select The <select> element
Development

No branches or pull requests