Technical review: Document customizable select listboxes#43352
Technical review: Document customizable select listboxes#43352chrisdavidmills wants to merge 5 commits intomdn:mainfrom
Conversation
|
I'm glad you built an example which does filtering, because I'm working on new primitives to help with that: https://open-ui.org/components/combobox.explainer/#associating-an-input-element-with-a-select-element One issue with the example is that it puts the input inside the select element, if I read it correctly - this goes against the content model and has parsing issues, so you should put it outside of the select before it instead. It would also be good to plan ahead for Was it explained anywhere that any size value greater than one opts you into listbox mode? |
| > [!NOTE] | ||
| > This article covers the background behind customizable selects and shows how to build "single dropdown" selects that take advantage of these features — that is, dropdown menus that display a single option at a time and allow a single option to be selected, created by `<select>`. | ||
| > | ||
| > For information on creating "listbox" selects — menus that display multiple options at once and allow a single option or multiple options to be selected, created by `<select multiple>` or `<select size="3">`, see [Customizable select listboxes](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select_listboxes). |
There was a problem hiding this comment.
Shouldn't — have a matching — ? I mean can you use comma as the end of the clause? Note, I'd also suggest here you don't need the "created by" bit.
| > For information on creating "listbox" selects — menus that display multiple options at once and allow a single option or multiple options to be selected, created by `<select multiple>` or `<select size="3">`, see [Customizable select listboxes](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select_listboxes). | |
| > For information on creating "listbox" selects — menus that display multiple options at once and allow a single option or multiple options to be selected — see [Customizable select listboxes](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select_listboxes). |
There was a problem hiding this comment.
Ha, yes — updated!
BTW, I'm going to implement these changes myself rather than accept the commits in the UI because I've already made other changes to the page, and I'm worried about merge conflicts. Sorry about that.
| ## Styling with CSS | ||
|
|
||
| The `<select>` element has historically been notoriously difficult to style productively with CSS, hence features being introduced to enable creating [fully customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select). | ||
| The `<select>` element has historically been notoriously difficult to style productively with CSS, hence features being introduced to enable creating fully customizable select elements. See the following guides for more information: |
There was a problem hiding this comment.
| The `<select>` element has historically been notoriously difficult to style productively with CSS, hence features being introduced to enable creating fully customizable select elements. See the following guides for more information: | |
| The `<select>` element has historically been difficult to style effectively with CSS. | |
| The following guides have information about newer features that have been introduced to enable fully customizable select elements: |
|
|
||
| ## Dropdown selects versus listboxes | ||
|
|
||
| When we talk about "dropdown" `<select>` elements, we are talking about the controls rendered for HTML like `<select>`. These feature a select button that, when pressed, shows a dropdown picker from which you can select different options. "Listbox" select elements on the other hand are controls rendered for HTML like `<select multiple>` or `<select size="3">`. These feature a box that shows multiple options at once, from which you can select one or multiple options. |
There was a problem hiding this comment.
The first sentence needs work. It reads like select is a select. I understand you're trying to differentiate a bare select with one that has attributes, but this doesn't work. The comparative example below works really well.
There was a problem hiding this comment.
Updated, to:
When we talk about "dropdown"
<select>elements, we are talking about controls featuring a select button that, when pressed, shows a dropdown picker from which you can select an option. These are specified using basic HTML such as<select>."Listbox"
<select>elements on the other hand are controls featuring a box that shows multiple options at once, from which you can select one or multiple options. You opt into rendering a "listbox" select by specifying themultipleattribute (to allow multiple selections) and/or asizevalue of more than1. For example,<select multiple>or<select size="3">.
|
|
||
| {{EmbedLiveSample("select-comparison", "100%", "200px")}} | ||
|
|
||
| It is simpler to style a customizable listbox `<select>` than it is to style the dropdown variant: |
There was a problem hiding this comment.
| It is simpler to style a customizable listbox `<select>` than it is to style the dropdown variant: | |
| A customizable listbox `<select>` is easier to style than the dropdown variant: |
|
|
||
| It is simpler to style a customizable listbox `<select>` than it is to style the dropdown variant: | ||
|
|
||
| - There is no dropdown picker, so you don't need to worry about styling it with the {{cssxref("::picker()", "::picker(select)")}} pseudo-element, its {{cssxref(":open")}} and closed states, etc. |
There was a problem hiding this comment.
Maybe
| - There is no dropdown picker, so you don't need to worry about styling it with the {{cssxref("::picker()", "::picker(select)")}} pseudo-element, its {{cssxref(":open")}} and closed states, etc. | |
| - There is no dropdown picker, so you don't need to worry about styling it with the {{cssxref("::picker()", "::picker(select)")}} pseudo-element, its {{cssxref(":open")}} and closed states, or the content of the picker in the closed state. |
There was a problem hiding this comment.
Actually, I see that this is covered in the next point. So what is "etc" here?
There was a problem hiding this comment.
I'm not sure. I've updated it to remove the etc. and just use "or" between the two.
| - You don't need to worry about styling the select button's icon using {{cssxref("::picker-icon")}}, or manipulating how the currently selected `<option>` is displayed inside the button using the {{htmlelement("selectedcontent")}} element. | ||
| - There is only a single container involved; you don't need to worry about the position of the picker relative to the button. | ||
|
|
||
| One of the major advantages of customizable `<select>` listboxes over "classic" select listboxes is that you can include a much wider variety of child elements inside them, which means great flexibility in terms of design and functionality. See [A more complex listbox](#a_more_complex_listbox) for an idea of what's possible. |
There was a problem hiding this comment.
Structually the fact that this is here feels wrong because this section is a comparision of dropdown vs select style, and here you're talking about new vs classic when we haven't even introduced why we needed a new customizable select.
I think I'd push this just below the very top parapraph following the structure "this is what a customizable listbox is", "These were historically hard to style", then this text. The end might be "below you'll see a simple listobx, but you can see A more complex listbox for an idea of what's possible."
There was a problem hiding this comment.
I can see your point. I've moved it up to the top. I deleted the link, because all of the examples in this article really help to show what's possible.
|
|
||
| The example renders like so: | ||
|
|
||
| {{EmbedLiveSample("complex-listbox", "100%", "360px")}} |
There was a problem hiding this comment.
With my last set of changes to the example, this now renders better now in Firefox, but it still doesn't quite render properly because Firefox doesn't support base-select and some of the related features (it currently only works fully in Chromium browsers).
To mitigate this issue, I've added support banners that show up in non-supporting browsers.
|
|
||
| In this example, we present the listbox options horizontally rather than vertically. | ||
|
|
||
| The HTML is the same as the previous examples, except that we've included an extra wrapper `<div>` to allow us to set a `width` on the `<select>` and then a different `width` on the wrapper so that all the `<options>` can be kept on one line and scrolled when the `<select>` becomes too narrow to fit them all. |
There was a problem hiding this comment.
| The HTML is the same as the previous examples, except that we've included an extra wrapper `<div>` to allow us to set a `width` on the `<select>` and then a different `width` on the wrapper so that all the `<options>` can be kept on one line and scrolled when the `<select>` becomes too narrow to fit them all. | |
| The HTML is the same as the previous examples, except that we've included an extra wrapper `<div>` to allow us to set a `width` on the `<select>` and then a different `width` on the wrapper so that all the `<option>` elements can be kept on one line and scrolled when the `<select>` becomes too narrow to fit them all. |
| } | ||
| ``` | ||
|
|
||
| Next, we style the three child containers — the filter `<input>`, the `.options` `<div>` that will contain our `<options>`, and the `.edit` `<div>` containing the link. Most notable here is that we give the `.options` `<div>` a fixed `height` and an {{cssxref("overflow-y")}} value of `scroll` so that the contained `<option>` elements will scroll inside it. |
There was a problem hiding this comment.
| Next, we style the three child containers — the filter `<input>`, the `.options` `<div>` that will contain our `<options>`, and the `.edit` `<div>` containing the link. Most notable here is that we give the `.options` `<div>` a fixed `height` and an {{cssxref("overflow-y")}} value of `scroll` so that the contained `<option>` elements will scroll inside it. | |
| Next, we style the three child containers — the filter `<input>`, the `.options` `<div>` that will contain our `<option>` elements, and the `.edit` `<div>` containing the link. Most notable here is that we give the `.options` `<div>` a fixed `height` and an {{cssxref("overflow-y")}} value of `scroll` so that the contained `<option>` elements will scroll inside it. |
There was a problem hiding this comment.
This has been rewritten anyway, and the problem fixed.
| } | ||
| ``` | ||
|
|
||
| Next, we give the `<option>` elements some extra padding to space them out horizontally, and a {{cssxref("position")}} value of relative so we can position their descendents relative to them. |
There was a problem hiding this comment.
Preferred spelling I understand
| Next, we give the `<option>` elements some extra padding to space them out horizontally, and a {{cssxref("position")}} value of relative so we can position their descendents relative to them. | |
| Next, we give the `<option>` elements some extra padding to space them out horizontally, and a {{cssxref("position")}} value of relative so we can position their descendants relative to them. |
| </select> | ||
| ``` | ||
|
|
||
| We start our CSS by styling the `<optgroup>` elements themselves. These are mostly rudimentary styles to make the optgroups look like containers for their descendent `<option>` elements. We've given them some {{cssxref("margin-top")}} to put some space between each optgroup, and between the top optgroup and the select button. |
There was a problem hiding this comment.
| We start our CSS by styling the `<optgroup>` elements themselves. These are mostly rudimentary styles to make the optgroups look like containers for their descendent `<option>` elements. We've given them some {{cssxref("margin-top")}} to put some space between each optgroup, and between the top optgroup and the select button. | |
| We start our CSS by styling the `<optgroup>` elements themselves. These are mostly rudimentary styles to make the optgroups look like containers for their descendant `<option>` elements. We've given them some {{cssxref("margin-top")}} to put some space between each optgroup, and between the top optgroup and the select button. |
There was a problem hiding this comment.
updated ;-)
| } | ||
| ``` | ||
|
|
||
| Most of the styling is fairly rudimentary, but we'll run throught it, pointing out anything significant along the way. The `<select>` element is given a `height` of `fit-content` so that it exactly fits its three child containers. |
There was a problem hiding this comment.
| Most of the styling is fairly rudimentary, but we'll run throught it, pointing out anything significant along the way. The `<select>` element is given a `height` of `fit-content` so that it exactly fits its three child containers. | |
| Most of the styling is fairly rudimentary, but we'll run through it, pointing out anything significant along the way. The `<select>` element is given a `height` of `fit-content` so that it exactly fits its three child containers. |
hamishwillee
left a comment
There was a problem hiding this comment.
Looks great. Examples are clear and good. Definitely worth having a separate doc for this kind of select element.
My main concern is about the introductory structure of the new doc - see comments. Needs to provide a more clear picture of what this adds over the old way.
@josepharhar this is really cool. I'm assuming that the declarative filter will just work? Coding the filter up is not that difficult, but it is still a fair chunk of JS.
Yeah, I should have thought about that a bit more carefully ;-) I've updated the example on the page to put the input outside the select instead.
I don't want to publish information on this until it is in the spec and shipped, but we can at least start to prepare. Is there a write-up anywhere of the features particular to this and how they differ from regular customization dropdown selects?
I've added a note to the new guide. I'll also aim to add explanatory notes to the |

Description
Chrome has supported Customizable
<select>elements (viaappearance: base-select) for single dropdown selects since version 135, and since 145, now supports it for listbox selects, e.g.<select size="3">or<select multiple>.See https://chromestatus.com/feature/6222145025867776.
This PR does a few things:
<optgroup>in customizable selects (this was previously glossed over).Motivation
Additional details
Related issues and pull requests
Fixes #43339