Open gregwhitworth opened 4 years ago
Bringing in my comment from the MSEdgeExplainer repo:
From the beginning I've been in favor of having new elements for the new controls as it also allows us to keep some native ones and specific needs for certain capabilities (window escape, etc). As we discussed in our explainer I'm also a fan of the built-in parts, while maybe leveraging WC parts under the hood being elements themselves as well so it is 100% apparent what is standard/ships with the UA and what is user land code.
What type of customizability are you trying to add to <select>
?
@Yay295 thanks for the question. While it's a bit long the explainer delves into the overall goal for every control that is currently shipping natively in browsers and exploration of new components/controls. TLDR; enable styling and extensibility of the built in controls by defining the antomy, states and behaviors within one specification within Open UI.
Some additional reading on the topic of the problem space and why this is worth investing in (I have some other concrete examples that I provide in my Open UI talk but haven't put in blog form yet):
Open UI will define the necessary anatomy which may result in new elements or psuedo elements, states, and other gaps. So to scope this one, the specific request as @dandclark has noted is that in order to unlock these new capabilities as some authors may desire the current <select>
and there may be web compat concerns. As such we can go a few different ways in order to unlock access to the new code. This methodology may itself need to be denoted on a case by case basis. Currently there are two possible options:
As outlined in the explainer it makes sense to introduce new elements for the various input types since their models and controller code are so different and this will allow this fork in the code. Let me know if that clarifies it for ya @Yay295
If the main goal is styling I don't see why we need a new attribute or element. It seems that appearance:none
or some such could allow for that.
@annevk out of curiosity did you read the explainer? Currently the parts of a select (and many other controls) are not exposed in order to enable the necessary styling and extensibility. As I outlined to the CSSWG we continue to do this but in an ad-hoc fashion due to inteop (see the file input psuedo element request by Mozilla). Open UI is a place where we're doing a holistic review and creating functional specifications that defines a control/component for web plat, component libs, etc as everyone is duplicating these (a single standardized functional specification currently does not exist).
If the main goal is styling I don't see why we need a new attribute or element. It seems that appearance:none or some such could allow for that.
There will be a need for appearance: none
but it will not be sufficient since the parts can't be accessed. The current <select>
has different implementations across UAs and also has additional capabilities that we can't keep due to security reasons (eg: escaping the bounds of the viewport) while enabling full style that is necessary. This also doesn't address the need for extensibility.
A new element makes a lot more sense to me.
If you go that route, I would suggest trying to unify <select>
with the current <input type="text">
+ <datalist>
combination. E.g. work on a <combobox>
element. Developers are consistently tripped up by the fact that these similar controls have very different interfaces.
@gregwhitworth well yes, you would also need pseudo-elements to get at the various bits. It would not give you the ability to add new bits necessarily, but it would address a large swath of the use cases. (And yes, part of disabling the native theming would be disabling the dialog drawing its own window.)
It would not give you the ability to add new bits necessarily, but it would address a large swath of the use cases.
And this is why psuedo elements are insufficient to cover the use cases. The explainer outlines that we'll leverage web component definitions leveraging slots and updating the definition of part to not solely be a hoist for CSS but to denote (even though it's implied) that the part has "controller" code attached to it by the component author. This will allow the UA (or component lib that builds according to Open UI) to wire up the necessary events & ARIA. This enables general extensibility without needing to completely recreate every interaction that a control has which can be very complex and is often not done with the same rigor across all implementations.
A new element makes a lot more sense to me.
Agreed
If you go that route, I would suggest trying to unify
I am open to this and am worth discussing it, I'd like to resolve on the differences/naming as a combobox and select as the majority of component libs, etc leverage the name select even if they appear as a combobox. Which is why we were initially leaning towards a select derivative.
The naming will be a hard problem regardless, as you've mentioned; I don't have any strong opinions there.
But I do feel somewhat firmly that there needs to be unification of "select where you can type" and "select where you cannot type". And ideally that would be at the web-developer-facing level. For example, one element with an optional attribute.
Stated in terms of use cases, I think developers transitioning from a fixed set of inputs to a fixed set of inputs + optional free-form text (e.g., modernizing a gender form field) should be able to do so easily. Currently, to transition from <select>
to <input>
+ <datalist>
, they have to re-do all of their markup, change their CSS selectors, and probably update their JavaScript code if they use things like selectedIndex
or options
. It would be great if in the future they could just add an HTML attribute, or similar, without those extra changes.
@domenic yep - there is agreement here generally and we've discussed this in general here in Open UI as this is the primary request for <select>
upon survey of 1400 webdevs and ~20 top web property partners in why they desire additional functionality. There are, to your point a desire to have a select solely be a button verse an actual input. I'll open a single issue on Open UI to discuss this (eg: should we bifurcate in control name solely to add an input rather than an element that behaves as button).
This is even more more odd with built in UA implementations as they allow type ahead functionality but don't show the actual user input which is just generally a bad UX. I think due to this I'd be more in favor of keeping the <select>
name and updating the anatomy to contain an input by default since that is actually how it's behaving. I'll link the Open UI issue here later this evening.
But I do feel somewhat firmly that there needs to be unification of "select where you can type" and "select where you cannot type". And ideally that would be at the web-developer-facing level. For example, one element with an optional attribute.
I just want to second this - the new element should unify these two use cases ("combo-box" and "drop-down") into a single control.
And I want to re-iterate my original comment: I think this should be a new element, not an attribute (which can be added and removed) on <select>
. While I understand the argument that this new thing "looks" like the old <select>
, there are many new behaviors that are incompatible with the old <select>
:
And inevitably there will be strange behaviors associated with adding or removing the opt-in attribute on <select>
such as removal of selections, resetting of state, etc. And as mentioned by @travisleithead, there will be questions about the timing of when the new behavior takes effect.
Consider what would happen here, if we went the attribute-on-select route:
Sample #1:
const combobox = document.createElement('select');
document.body.appendChild(combobox);
combobox.addAttribute('newbehavior','true'); // Opt in!
combobox.innerHTML = '<option><img src="cat.jpg">Cat</option><option><img src="dog.jpg">Dog</option>';
// Here, we have a fancy, new <select> with images of cats and dogs
Sample #2:
const combobox = document.createElement('select');
document.body.appendChild(combobox);
combobox.innerHTML = '<option><img src="cat.jpg">Cat</option><option><img src="dog.jpg">Dog</option>';
combobox.addAttribute('newbehavior','true'); // Opt in, but a little late
// Boo! No images here, because we opted in after innerHTML, and the parser removed the <img> tags.
(Note that <input>
+ <datalist>
also works for other controls (some in theory), e.g., range, color, and email.)
I second the proposal for a new <combobox>
element, or whatever it ends up being called to unify <select>
and <input>
+<datalist>
.
A few thoughts:
<datalist>
to specify the autocomplete options in an <input>
, you cannot use it to specify the options in a <select>
, which in some cases forces them to duplicate markup. So it may be a good idea to allow both in the new element.<select>
), a behavior that is not possible with an <input>
, where selecting an item from the <datalist>
enters that option's value in the input. A new element can also address this issue.Related issue: https://github.com/whatwg/html/issues/6733
@dandclark opened this issue on the repo that contains the explainer for this. For context, we released an explainer that attempts to explain a web platform control definition for defining components going forward. This requires HTML modifications across the WHATWG but to keep this one scoped. Here is the outline from Dan in the initial issue: