From 4e4b77cb9af3e91c51af5b1d654acf26e2bdd496 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Wed, 5 Mar 2025 17:58:00 +0000
Subject: [PATCH 01/15] Document customizable <select> elements

---
 .../forms/customizable_select/index.md        | 372 ++++++++++++++++++
 1 file changed, 372 insertions(+)
 create mode 100644 files/en-us/learn_web_development/extensions/forms/customizable_select/index.md

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
new file mode 100644
index 000000000000000..08e17511b579abf
--- /dev/null
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -0,0 +1,372 @@
+---
+title: Customizable select elements
+slug: Learn_web_development/Extensions/Forms/Customizable_select
+page-type: learn-module-chapter
+---
+
+{{LearnSidebar}}
+
+This article explains how to use a number of HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements. This includes having full control over styling the select button, drop-down picker, arrow icon, checkbox to indicate which item is currently selected, each individual {{htmlelement("option")}} element, and more besides.
+
+## Background
+
+Traditionally it has been difficult to customize the look and feel of `<select>` elements because they contain internals that are styled at the operating system level, which can't be targeted using CSS. This includes the drop-down picker, the arrow icon, etc.
+
+Previously the best option we had available, aside from using a custom JavaScript library, was to set an {{cssxref("appearance")}} value of `none` on the `<select>` element to strip away some of the OS-level styling, and then use CSS to customize the bits we can control. This technique is explained in [Advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
+
+Customizable `<select>` elements provide a solution to these issues. They allow you to build examples like the following, using only HTML and CSS:
+
+{{EmbedLiveSample("full-render", "100%", "200px")}}
+
+We'll show you how to build this example in the sections below.
+
+## What features comprise a customizable select?
+
+You can build customizable `<select>` elements using the following HTML and CSS features:
+
+- Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be easily designed to fall back to classic selects in non-supporting browsers.
+- The {{htmlelement("selectedcontent")}} element, which under the hood provides a {{htmlelement("slot")}} into which is placed the contents of the currently-selected `<option>`. This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}**, as it is the button you need to press to open the drop-down menu.
+- The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`.
+- The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
+- The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
+- The {{cssxref("::picker-icon")}} pseudo-element, which targets the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side.
+- The {{cssxref(":checked")}} pseudo-class, which targets the currently-selected `<option>` element.
+- The {{cssxref("::checkmark")}} pseudo-element, which targets the checkmark placed inside the currently-selected `<option>` element to provide a visual indication of which one is selected.
+
+In addition, the select `<button>` and the picker have the following behavior assigned to them automatically:
+
+- They have an invoker/popover relationship, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class. See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior.
+- The have an implicit anchor reference, meaning that the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning), and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+
+> [!NOTE]
+> You can check browser support for customizable `<select>` by viewing the browser compatibility tables on the reference pages listed above.
+
+Let's look at all of the above features in action, by walking through the example you saw earlier.
+
+## Customizable select markup
+
+Our example is a typical {{htmlelement("select")}} menu that allows you to choose a pet. The markup is as follows:
+
+```html live-sample___plain-render live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+<form>
+  <p>
+    <label for="pet-select">Select pet:</label>
+    <select id="pet-select">
+      <button>
+        <selectedcontent></selectedcontent>
+      </button>
+
+      <option value="">Please select a pet</option>
+      <option value="cat">
+        <span class="icon">🐱</span><span class="option-label">Cat</span>
+      </option>
+      <option value="dog">
+        <span class="icon">🐶</span><span class="option-label">Dog</span>
+      </option>
+      <option value="tortoise">
+        <span class="icon">🐹</span><span class="option-label">Hamster</span>
+      </option>
+      <option value="parrot">
+        <span class="icon">🐔</span><span class="option-label">Chicken</span>
+      </option>
+      <option value="fish">
+        <span class="icon">🐟</span><span class="option-label">Fish</span>
+      </option>
+      <option value="snake">
+        <span class="icon">🐍</span><span class="option-label">Snake</span>
+      </option>
+    </select>
+  </p>
+</form>
+```
+
+This is nearly the same as "classic" `<select>` markup, with the following differences:
+
+- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element provides a {{htmlelement("slot")}} into which is placed the contents of the currently-selected {{htmlelement("option")}}. This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fill in the selected value inside the select button implicitly, but you won't be able to select it using CSS.
+- The rest of the `<select>` contents represents the picker (the `<select>` drop-down menu). This obviously includes the `<option>` elements representing the different choices in the picker, but you can also include other content if desired.
+- Traditionally, `<option>` elements could only contain text, but in a customizable select you can include markup structures including images and more besides. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
+
+  > [!NOTE]
+  > Because the `<option>` content can contain multi-level DOM sub-trees, not just text nodes, there are rules concerning how the browser should extract the [current `<select>` value](/en-US/docs/Web/API/HTMLSelectElement/value) via JavaScript. The selected `<option>` element's {{domxref("Node.textContent", "textContent")}} property value is retrieved, {{jsxref("String.prototype.trim", "trim()")}} is run on it, and the result is set as the `<select>` value.
+
+This design allows non-supporting browsers to fall back to a classic `<select>` menu. The `<button><selectedcontent></selectedcontent></button>` structure will be ignored completely, and the non-text `<option>` contents will be stripped out to just leave the text node contents, but the result will still function.
+
+## Opting in to the custom select rendering
+
+To opt-in to the custom select functionality, your `<select>` element and its picker (represented by the `::picker(select)` pseudo-element) both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+
+```css live-sample___plain-render live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+select,
+::picker(select) {
+  appearance: base-select;
+}
+```
+
+```css hidden live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+* {
+  box-sizing: border-box;
+}
+
+html {
+  font-family: Arial, Helvetica, sans-serif;
+}
+
+body {
+  width: 100%;
+  padding: 0 10px;
+  max-width: 480px;
+  margin: 0 auto;
+}
+
+h2 {
+  font-size: 1.2rem;
+}
+
+p {
+  display: flex;
+  gap: 10px;
+}
+
+label {
+  width: fit-content;
+  align-self: center;
+}
+
+select {
+  flex: 1;
+}
+```
+
+You can choose to opt-in one or the other, but in most cases you'll want to opt-in both.
+
+Once this is done, the result is a very plain rendering of a `<select>` element:
+
+{{EmbedLiveSample("plain-render", "100%", "200px")}}
+
+You are now free to style this in any way you want. To begin with, we decided to give the `<select>` a custom {{cssxref("border")}}, {{cssxref("background")}} (which changes on {{cssxref(":hover")}} or {{cssxref(":focus")}}), and {{cssxref("padding")}}, plus a {{cssxref("transition")}} so that the background change animates smoothly:
+
+```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+select {
+  border: 2px solid #ddd;
+  background: #eee;
+  padding: 10px;
+  transition: 0.4s;
+}
+
+select:hover,
+select:focus {
+  background: #ddd;
+}
+```
+
+## Styling the picker icon
+
+To style the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side — you can target it with the {{cssxref("::picker-icon")}} pseudo-element. In the following code we give the icon a custom {{cssxref("color")}} and a `transition` so that changes to its {{cssxref("rotate")}} property are smoothly animated:
+
+```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+select::picker-icon {
+  color: #999;
+  transition: 0.4s rotate;
+}
+```
+
+Next up, we combine `::picker-icon` with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the picker is open — to give the icon a `rotate` value of `180deg` when the `<select>` is opened.
+
+```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
+select:open::picker-icon {
+  rotate: 180deg;
+}
+```
+
+Let's have a look at our work so far — note how the picker arrow rotates smoothly through 180 degrees when the `<select>` opens and closes:
+
+{{EmbedLiveSample("second-render", "100%", "200px")}}
+
+## Styling the picker drop-down menu
+
+The select picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As we said earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
+
+For now, we'll just use this to remove the picker's default black {{cssxref("border")}} border:
+
+```css live-sample___third-render live-sample___fourth-render live-sample___full-render
+::picker(select) {
+  border: none;
+}
+```
+
+Now we'll style our `<option>` elements. First of all, we'll lay them out with [flexbox](/en-US/docs/Web/CSS/CSS_flexible_box_layout), aligning them all to the start of the flex container and including a `20px` {{cssxref("gap")}} between each one. We also give each `<option>` the same {{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("padding")}}, and {{cssxref("transition")}} as the `<select>`, to provide a consistent look and feel:
+
+```css live-sample___third-render live-sample___fourth-render live-sample___full-render
+option {
+  display: flex;
+  justify-content: flex-start;
+  gap: 20px;
+
+  border: 2px solid #ddd;
+  background: #eee;
+  padding: 10px;
+  transition: 0.4s;
+}
+```
+
+> [!NOTE]
+> Customizable `<select>` element `<option>`s have `display: flex` set on them by default, but we included this setting in our stylesheet anyway so it is clear what is going on.
+
+Next, we use a combination of {{cssxref(":first-of-type")}}, {{cssxref(":last-of-type")}}, and {{cssxref(":not()")}} to set an appropriate {{cssxref("border-radius")}} on the top and bottom corners of the picker, and remove the {{cssxref("border-bottom")}} from all `<option>` elements except the last one so the borders don't look messy and doubled-up:
+
+```css live-sample___third-render live-sample___fourth-render live-sample___full-render
+option:first-of-type {
+  border-radius: 8px 8px 0 0;
+}
+
+option:last-of-type {
+  border-radius: 0 0 8px 8px;
+}
+
+option:not(option:last-of-type) {
+  border-bottom: none;
+}
+```
+
+We next set a different `background` color on the odd-numbered `<options>` using {{cssxref(":nth-of-type()", ":nth-of-type(odd)")}} to implement zebra-striping, and set a different `background` color on the `<options>` on focus and hover, to provide a useful visual highlight during selection:
+
+```css live-sample___third-render live-sample___fourth-render live-sample___full-render
+option:nth-of-type(odd) {
+  background: #fff;
+}
+
+option:hover,
+option:focus {
+  background: plum;
+}
+```
+
+Finally for this section, we increase the {{cssxref("font-size")}} set on the `<option>` icons (contained within `<span>` elements with a class of `icon`) to make them bigger, and use {{cssxref("text-box")}} to remove some of the annoying spacing at the block-start and block-end edges of the icon emojis, making them align better with the text labels
+
+```css live-sample___third-render live-sample___fourth-render live-sample___full-render
+option .icon {
+  font-size: 1.6rem;
+  text-box: trim-both cap alphabetic;
+}
+```
+
+Our example now renders like this:
+
+{{EmbedLiveSample("third-render", "100%", "200px")}}
+
+## Adjusting the styling of the selected option contents inside the select button
+
+If you select any pet option from the last few live examples, you'll notice a problem — the pet icons cause the select `<button>` to increase in height, which also changes the position of the picker icon, and there is no spacing between the option icon and label — not a great look.
+
+This can be fixed by hiding the icon when it is contained inside the `<selectedcontent>` slot, which represents the contents of the selected `<option>` as they appear inside the select `<button>`. In our example, we'll hide it using {{cssxref("display", "display: none")}}:
+
+```css live-sample___fourth-render live-sample___full-render
+selectedcontent .icon {
+  display: none;
+}
+```
+
+This does not affect the styling of the `<option>` contents as they appear inside the picker.
+
+## Styling the currently selected option
+
+To style the currently selected `<option>` as it appears inside the picker, you can target it using the {{cssxref(":checked")}} pseudo-class. We don't have much need for this inside our demo, so we'll just use this to set the selected `<option>` element's {{cssxref("font-weight")}} to `bold`, for demo purposes:
+
+```css live-sample___fourth-render live-sample___full-render
+option:checked {
+  font-weight: bold;
+}
+```
+
+## Styling the current selection checkmark
+
+You've probably noticed that when you open the picker to make a selection, the currently selected `<option>` has a checkmark at its inline-start end. This checkmark can be targeted using the {{cssxref("::checkmark")}} pseudo-element. For example, you might want to hide this checkmark (for example, via `display: none`).
+
+In our demo, we chose to do something a bit more interesting with it — earlier on we established that our `<option>` elements are laid out horizontally using flexbox, with the flex items being aligned to the start of the row. In the below rule, we are moving the checkmark from the start of the row to the end by setting an {{cssxref("order")}} value on it greater than `0`, and aligning it to the end of the row using an `auto` {{cssxref("margin-left")}} value (see [Alignment and auto margins](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_flexbox#alignment_and_auto_margins)).
+
+We've also set the value of the {{cssxref("content")}} property to a different emoji, to choose a different icon to display.
+
+```css live-sample___fourth-render live-sample___full-render
+option::checkmark {
+  order: 1;
+  margin-left: auto;
+  content: "☑️";
+}
+```
+
+Let's check in again on how our example is rendering. The updated state after the last three sections is as follows:
+
+{{EmbedLiveSample("fourth-render", "100%", "200px")}}
+
+## Animating the picker drop-down using popover states
+
+Earlier on, we mentioned that a customizable `<select>` element's select `button` and picker have an invoker/popover relationship, as described in [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using). There are many advantages that this brings to `<select>` elements, but one that we want to use in our example is the ability to animate between popover hidden and showing states using transitions and the {{cssxref(":popover-open")}} pseudo-class (which represents popovers in the showing state).
+
+We will walk through the technique quickly in this section — read [Animating popovers](/en-US/docs/Web/API/Popover_API/Using#animating_popovers) for a more detailed description.
+
+First of all, we select the picker using `::picker(select)` and set an {{cssxref("opacity")}} value of `0` on it, and a `transition` value of `all 0.4s allow-discrete`. This causes all properties that change value when the popover state changes from hidden to showing to animate. This includes `opacity`, but it also includes two discrete properties whose values are set by the browser default styles (the [`allow-discrete`](/en-US/docs/Web/CSS/transition-behavior#allow-discrete) value is needed to enable discrete property animations):
+
+- {{cssxref("display")}}
+  - : The `display` values changes from `none` to `block` when the popover changes state from hidden to shown. This needs to be animated to ensure that other transitions are visible.
+- {{cssxref("overlay")}}
+  - : The `overlay` value changes from `none` to `auto` when the popover changes state from hidden to shown, to promote it to the {{glossary("top layer")}}, then back again when it is hidden to remove it. This needs to be animated to ensure the removal of the popover from the top layer is deferred until the transition completes, again ensuring the transition is visible.
+
+```css live-sample___full-render
+::picker(select) {
+  opacity: 0;
+  transition: all 0.4s allow-discrete;
+}
+```
+
+Next, we select the picker in the showing state using `::picker(select):popover-open` and set the `opacity` value to `1` — this is the end state of our transition:
+
+```css live-sample___full-render
+::picker(select):popover-open {
+  opacity: 1;
+}
+```
+
+Finally, because we are creating a transtition on an element while it is moving from `display: none` to a `display` value that makes it visible, we need to specify the transition's starting state inside an {{cssxref("@opacity")}} block:
+
+```css live-sample___full-render
+@starting-style {
+  ::picker(select):popover-open {
+    opacity: 0;
+  }
+}
+```
+
+These rules work together to make our `<select>` picker smoothly fade in and fade out when the `<select>` is opeed and closed.
+
+## Positioning the picker using anchor positioning
+
+We also previously mentioned that a customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties, and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+
+In our demo, we set the positioning of the picker relative to its anchor by using the {{cssxref("anchor()")}} function inside its {{cssxref("top")}} and {{cssxref("left")}} property values:
+
+```css live-sample___full-render
+::picker(select) {
+  top: calc(anchor(bottom) + 1px);
+  left: anchor(10%);
+}
+```
+
+The results in the top edge of the picker always being positioned 1 pixel down from the bottom edge of the select `<button>`, and the left edge of the picker always being positioned `10%` of the select `<button>`'s width across from its left edge.
+
+## Final result
+
+After the last two section, the final updated state of our `<select>` is rendered like this:
+
+{{EmbedLiveSample("full-render", "100%", "200px")}}
+
+## Multiple selects
+
+xx
+
+## Optgroups
+
+xx
+
+## See also
+
+xx

From db40b51e7d384d29de8a164db19df0c40a941d2b Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Wed, 5 Mar 2025 18:12:03 +0000
Subject: [PATCH 02/15] fix typo

---
 .../extensions/forms/customizable_select/index.md               | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 08e17511b579abf..2648370eab5b41e 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -36,7 +36,7 @@ You can build customizable `<select>` elements using the following HTML and CSS
 In addition, the select `<button>` and the picker have the following behavior assigned to them automatically:
 
 - They have an invoker/popover relationship, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class. See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior.
-- The have an implicit anchor reference, meaning that the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning), and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+- They have an implicit anchor reference, meaning that the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning), and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
 
 > [!NOTE]
 > You can check browser support for customizable `<select>` by viewing the browser compatibility tables on the reference pages listed above.

From e55d3180ee5c8972c38a19b462fb5aea29d296a7 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Thu, 6 Mar 2025 19:44:47 +0000
Subject: [PATCH 03/15] Finish guide

---
 .../forms/customizable_select/index.md        | 87 ++++++++++---------
 1 file changed, 48 insertions(+), 39 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 2648370eab5b41e..55084597f8b22d8 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -10,15 +10,15 @@ This article explains how to use a number of HTML and CSS features together to c
 
 ## Background
 
-Traditionally it has been difficult to customize the look and feel of `<select>` elements because they contain internals that are styled at the operating system level, which can't be targeted using CSS. This includes the drop-down picker, the arrow icon, etc.
+Traditionally it has been difficult to customize the look and feel of `<select>` elements because they contain internals that are styled at the operating system level, which can't be targeted using CSS. This includes the drop-down picker, arrow icon, etc.
 
-Previously the best option we had available, aside from using a custom JavaScript library, was to set an {{cssxref("appearance")}} value of `none` on the `<select>` element to strip away some of the OS-level styling, and then use CSS to customize the bits we can control. This technique is explained in [Advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
+Previously, the best available option aside from using a custom JavaScript library was to set an {{cssxref("appearance")}} value of `none` on the `<select>` element to strip away some of the OS-level styling, and then use CSS to customize the bits that cna be styled. This technique is explained in [Advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
 
 Customizable `<select>` elements provide a solution to these issues. They allow you to build examples like the following, using only HTML and CSS:
 
 {{EmbedLiveSample("full-render", "100%", "200px")}}
 
-We'll show you how to build this example in the sections below.
+You'll find out how to build this example in the sections below.
 
 ## What features comprise a customizable select?
 
@@ -143,7 +143,7 @@ Once this is done, the result is a very plain rendering of a `<select>` element:
 
 {{EmbedLiveSample("plain-render", "100%", "200px")}}
 
-You are now free to style this in any way you want. To begin with, we decided to give the `<select>` a custom {{cssxref("border")}}, {{cssxref("background")}} (which changes on {{cssxref(":hover")}} or {{cssxref(":focus")}}), and {{cssxref("padding")}}, plus a {{cssxref("transition")}} so that the background change animates smoothly:
+You are now free to style this in any way you want. To begin with, the `<select>` element has custom {{cssxref("border")}}, {{cssxref("background")}} (which changes on {{cssxref(":hover")}} or {{cssxref(":focus")}}), and {{cssxref("padding")}} values set, plus a {{cssxref("transition")}} so that the background change animates smoothly:
 
 ```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select {
@@ -161,7 +161,7 @@ select:focus {
 
 ## Styling the picker icon
 
-To style the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side — you can target it with the {{cssxref("::picker-icon")}} pseudo-element. In the following code we give the icon a custom {{cssxref("color")}} and a `transition` so that changes to its {{cssxref("rotate")}} property are smoothly animated:
+To style the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side — you can target it with the {{cssxref("::picker-icon")}} pseudo-element. In the following code gives the icon a custom {{cssxref("color")}} and a `transition` so that changes to its {{cssxref("rotate")}} property are smoothly animated:
 
 ```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select::picker-icon {
@@ -170,7 +170,7 @@ select::picker-icon {
 }
 ```
 
-Next up, we combine `::picker-icon` with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the picker is open — to give the icon a `rotate` value of `180deg` when the `<select>` is opened.
+Next up, `::picker-icon` is combined with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the picker is open — to give the icon a `rotate` value of `180deg` when the `<select>` is opened.
 
 ```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select:open::picker-icon {
@@ -178,15 +178,15 @@ select:open::picker-icon {
 }
 ```
 
-Let's have a look at our work so far — note how the picker arrow rotates smoothly through 180 degrees when the `<select>` opens and closes:
+Let's have a look at the work so far — note how the picker arrow rotates smoothly through 180 degrees when the `<select>` opens and closes:
 
 {{EmbedLiveSample("second-render", "100%", "200px")}}
 
 ## Styling the picker drop-down menu
 
-The select picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As we said earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
+The select picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As mentioned earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
 
-For now, we'll just use this to remove the picker's default black {{cssxref("border")}} border:
+First of all, the picker's default black {{cssxref("border")}} border is removed:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 ::picker(select) {
@@ -194,7 +194,7 @@ For now, we'll just use this to remove the picker's default black {{cssxref("bor
 }
 ```
 
-Now we'll style our `<option>` elements. First of all, we'll lay them out with [flexbox](/en-US/docs/Web/CSS/CSS_flexible_box_layout), aligning them all to the start of the flex container and including a `20px` {{cssxref("gap")}} between each one. We also give each `<option>` the same {{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("padding")}}, and {{cssxref("transition")}} as the `<select>`, to provide a consistent look and feel:
+Now the `<option>` elements are styled. They are laid out with [flexbox](/en-US/docs/Web/CSS/CSS_flexible_box_layout), aligning them all to the start of the flex container and including a `20px` {{cssxref("gap")}} between each one. Each `<option>` is also given the same {{cssxref("border")}}, {{cssxref("background")}}, {{cssxref("padding")}}, and {{cssxref("transition")}} as the `<select>`, to provide a consistent look and feel:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 option {
@@ -210,9 +210,9 @@ option {
 ```
 
 > [!NOTE]
-> Customizable `<select>` element `<option>`s have `display: flex` set on them by default, but we included this setting in our stylesheet anyway so it is clear what is going on.
+> Customizable `<select>` element `<option>`s have `display: flex` set on them by default, but it is included in our stylesheet anyway to clarify what is going on.
 
-Next, we use a combination of {{cssxref(":first-of-type")}}, {{cssxref(":last-of-type")}}, and {{cssxref(":not()")}} to set an appropriate {{cssxref("border-radius")}} on the top and bottom corners of the picker, and remove the {{cssxref("border-bottom")}} from all `<option>` elements except the last one so the borders don't look messy and doubled-up:
+Next, a combination of the {{cssxref(":first-of-type")}}, {{cssxref(":last-of-type")}}, and {{cssxref(":not()")}} pseudo-classes is used to set an appropriate {{cssxref("border-radius")}} on the top and bottom corners of the picker, and remove the {{cssxref("border-bottom")}} from all `<option>` elements except the last one so the borders don't look messy and doubled-up:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 option:first-of-type {
@@ -228,7 +228,7 @@ option:not(option:last-of-type) {
 }
 ```
 
-We next set a different `background` color on the odd-numbered `<options>` using {{cssxref(":nth-of-type()", ":nth-of-type(odd)")}} to implement zebra-striping, and set a different `background` color on the `<options>` on focus and hover, to provide a useful visual highlight during selection:
+Next a different `background` color is set on the odd-numbered `<options>` using {{cssxref(":nth-of-type()", ":nth-of-type(odd)")}} to implement zebra-striping, and a different `background` color is set on the `<options>` on focus and hover, to provide a useful visual highlight during selection:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 option:nth-of-type(odd) {
@@ -241,7 +241,7 @@ option:focus {
 }
 ```
 
-Finally for this section, we increase the {{cssxref("font-size")}} set on the `<option>` icons (contained within `<span>` elements with a class of `icon`) to make them bigger, and use {{cssxref("text-box")}} to remove some of the annoying spacing at the block-start and block-end edges of the icon emojis, making them align better with the text labels
+Finally for this section, a larger {{cssxref("font-size")}} is set on the `<option>` icons (contained within `<span>` elements with a class of `icon`) to make them bigger, and the {{cssxref("text-box")}} property is used to remove some of the annoying spacing at the block-start and block-end edges of the icon emojis, making them align better with the text labels:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 option .icon {
@@ -258,7 +258,7 @@ Our example now renders like this:
 
 If you select any pet option from the last few live examples, you'll notice a problem — the pet icons cause the select `<button>` to increase in height, which also changes the position of the picker icon, and there is no spacing between the option icon and label — not a great look.
 
-This can be fixed by hiding the icon when it is contained inside the `<selectedcontent>` slot, which represents the contents of the selected `<option>` as they appear inside the select `<button>`. In our example, we'll hide it using {{cssxref("display", "display: none")}}:
+This can be fixed by hiding the icon when it is contained inside the `<selectedcontent>` slot, which represents the contents of the selected `<option>` as they appear inside the select `<button>`. In our example, it is hidden using {{cssxref("display", "display: none")}}:
 
 ```css live-sample___fourth-render live-sample___full-render
 selectedcontent .icon {
@@ -270,7 +270,7 @@ This does not affect the styling of the `<option>` contents as they appear insid
 
 ## Styling the currently selected option
 
-To style the currently selected `<option>` as it appears inside the picker, you can target it using the {{cssxref(":checked")}} pseudo-class. We don't have much need for this inside our demo, so we'll just use this to set the selected `<option>` element's {{cssxref("font-weight")}} to `bold`, for demo purposes:
+To style the currently selected `<option>` as it appears inside the picker, you can target it using the {{cssxref(":checked")}} pseudo-class. This is used to set the selected `<option>` element's {{cssxref("font-weight")}} to `bold`:
 
 ```css live-sample___fourth-render live-sample___full-render
 option:checked {
@@ -282,9 +282,9 @@ option:checked {
 
 You've probably noticed that when you open the picker to make a selection, the currently selected `<option>` has a checkmark at its inline-start end. This checkmark can be targeted using the {{cssxref("::checkmark")}} pseudo-element. For example, you might want to hide this checkmark (for example, via `display: none`).
 
-In our demo, we chose to do something a bit more interesting with it — earlier on we established that our `<option>` elements are laid out horizontally using flexbox, with the flex items being aligned to the start of the row. In the below rule, we are moving the checkmark from the start of the row to the end by setting an {{cssxref("order")}} value on it greater than `0`, and aligning it to the end of the row using an `auto` {{cssxref("margin-left")}} value (see [Alignment and auto margins](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_flexbox#alignment_and_auto_margins)).
+You could also choose to do something a bit more interesting with it — earlier on the `<option>` elements were laid out horizontally using flexbox, with the flex items being aligned to the start of the row. In the below rule, the checkmark is moved from the start of the row to the end by setting an {{cssxref("order")}} value on it greater than `0`, and aligning it to the end of the row using an `auto` {{cssxref("margin-left")}} value (see [Alignment and auto margins](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_flexbox#alignment_and_auto_margins)).
 
-We've also set the value of the {{cssxref("content")}} property to a different emoji, to choose a different icon to display.
+Finally, the value of the {{cssxref("content")}} property is set to a different emoji, to set a different icon to display.
 
 ```css live-sample___fourth-render live-sample___full-render
 option::checkmark {
@@ -294,22 +294,17 @@ option::checkmark {
 }
 ```
 
-Let's check in again on how our example is rendering. The updated state after the last three sections is as follows:
+Let's check in again on how the example is rendering. The updated state after the last three sections is as follows:
 
 {{EmbedLiveSample("fourth-render", "100%", "200px")}}
 
 ## Animating the picker drop-down using popover states
 
-Earlier on, we mentioned that a customizable `<select>` element's select `button` and picker have an invoker/popover relationship, as described in [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using). There are many advantages that this brings to `<select>` elements, but one that we want to use in our example is the ability to animate between popover hidden and showing states using transitions and the {{cssxref(":popover-open")}} pseudo-class (which represents popovers in the showing state).
+The customizable `<select>` element's select `button` and picker are automatically given an invoker/popover relationship, as described in [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using). There are many advantages that this brings to `<select>` elements; our example takes advantage of the ability to animate between popover hidden and showing states using transitions. The {{cssxref(":popover-open")}} pseudo-class represents popovers in the showing state.
 
-We will walk through the technique quickly in this section — read [Animating popovers](/en-US/docs/Web/API/Popover_API/Using#animating_popovers) for a more detailed description.
+The technique is covered quickly in this section — read [Animating popovers](/en-US/docs/Web/API/Popover_API/Using#animating_popovers) for a more detailed description.
 
-First of all, we select the picker using `::picker(select)` and set an {{cssxref("opacity")}} value of `0` on it, and a `transition` value of `all 0.4s allow-discrete`. This causes all properties that change value when the popover state changes from hidden to showing to animate. This includes `opacity`, but it also includes two discrete properties whose values are set by the browser default styles (the [`allow-discrete`](/en-US/docs/Web/CSS/transition-behavior#allow-discrete) value is needed to enable discrete property animations):
-
-- {{cssxref("display")}}
-  - : The `display` values changes from `none` to `block` when the popover changes state from hidden to shown. This needs to be animated to ensure that other transitions are visible.
-- {{cssxref("overlay")}}
-  - : The `overlay` value changes from `none` to `auto` when the popover changes state from hidden to shown, to promote it to the {{glossary("top layer")}}, then back again when it is hidden to remove it. This needs to be animated to ensure the removal of the popover from the top layer is deferred until the transition completes, again ensuring the transition is visible.
+First of all, the picker is selected using `::picker(select)`, and given an {{cssxref("opacity")}} value of `0` and a `transition` value of `all 0.4s allow-discrete`. This causes all properties that change value when the popover state changes from hidden to showing to animate.
 
 ```css live-sample___full-render
 ::picker(select) {
@@ -318,7 +313,17 @@ First of all, we select the picker using `::picker(select)` and set an {{cssxref
 }
 ```
 
-Next, we select the picker in the showing state using `::picker(select):popover-open` and set the `opacity` value to `1` — this is the end state of our transition:
+The list of transitioned properties features `opacity`, however it also includes two discrete properties whose values are set by the browser default styles:
+
+- {{cssxref("display")}}
+  - : The `display` values changes from `none` to `block` when the popover changes state from hidden to shown. This needs to be animated to ensure that other transitions are visible.
+- {{cssxref("overlay")}}
+  - : The `overlay` value changes from `none` to `auto` when the popover changes state from hidden to shown, to promote it to the {{glossary("top layer")}}, then back again when it is hidden to remove it. This needs to be animated to ensure the removal of the popover from the top layer is deferred until the transition completes, again ensuring the transition is visible.
+
+> [!NOTE]
+> The [`allow-discrete`](/en-US/docs/Web/CSS/transition-behavior#allow-discrete) value is needed to enable discrete property animations.
+
+Next, the picker is selected in the showing state using `::picker(select):popover-open` and given an `opacity` value to `1` — this is the end state of the transition:
 
 ```css live-sample___full-render
 ::picker(select):popover-open {
@@ -326,7 +331,7 @@ Next, we select the picker in the showing state using `::picker(select):popover-
 }
 ```
 
-Finally, because we are creating a transtition on an element while it is moving from `display: none` to a `display` value that makes it visible, we need to specify the transition's starting state inside an {{cssxref("@opacity")}} block:
+Finally, because the picker is being transitioned while it is moving from `display: none` to a `display` value that makes it visible, the transition's starting state has to be specified inside a {{cssxref("@starting-state")}} block:
 
 ```css live-sample___full-render
 @starting-style {
@@ -336,13 +341,13 @@ Finally, because we are creating a transtition on an element while it is moving
 }
 ```
 
-These rules work together to make our `<select>` picker smoothly fade in and fade out when the `<select>` is opeed and closed.
+These rules work together to make the `<select>` picker smoothly fade in and fade out when the `<select>` is opeed and closed.
 
 ## Positioning the picker using anchor positioning
 
-We also previously mentioned that a customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties, and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+A customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties, and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
 
-In our demo, we set the positioning of the picker relative to its anchor by using the {{cssxref("anchor()")}} function inside its {{cssxref("top")}} and {{cssxref("left")}} property values:
+In our demo, the position of the picker is set relative to its anchor by using the {{cssxref("anchor()")}} function inside its {{cssxref("top")}} and {{cssxref("left")}} property values:
 
 ```css live-sample___full-render
 ::picker(select) {
@@ -351,7 +356,7 @@ In our demo, we set the positioning of the picker relative to its anchor by usin
 }
 ```
 
-The results in the top edge of the picker always being positioned 1 pixel down from the bottom edge of the select `<button>`, and the left edge of the picker always being positioned `10%` of the select `<button>`'s width across from its left edge.
+This results in the top edge of the picker always being positioned 1 pixel down from the bottom edge of the select `<button>`, and the left edge of the picker always being positioned `10%` of the select `<button>`'s width across from its left edge.
 
 ## Final result
 
@@ -359,14 +364,18 @@ After the last two section, the final updated state of our `<select>` is rendere
 
 {{EmbedLiveSample("full-render", "100%", "200px")}}
 
-## Multiple selects
-
-xx
+## Customizing other classic select features
 
-## Optgroups
+The above sections have covered all the new functionality available in customizable selects, and shown how it interacts with both classic single-line selects, and related modern features such as popovers and anchor positioning. There are some other `<select>` element features not mentioned above; this section talks about how they work alongside customizable selects:
 
-xx
+- [`<select multiple>`](/en-US/docs/Web/HTML/Attributes/multiple)
+  - : When the `multiple` attribute is set on customizable `<select>` elements, the styling works pretty much how you would expect — the styling applied to the `<option>` elements is presented as-is in the multiple select box, and the outer box itself is giving the same styling as the select `<button>` in the single select. Any styling related to the showing and hiding of the picker is ignored.
+- {{htmlelement("optgroup")}}
+  - : The default styling of `<optgroup>` elements is the same as in classic `<select>` elements — bolded and indented less than the contained options. You need to make sure to style the `<optgroup>` elements so they fit into the overall design, and bear in mind that they will behave just as containers are expected to behave in conventioal HTML.
 
 ## See also
 
-xx
+- {{htmlelement("select")}}, {{htmlelement("option")}}, {{htmlelement("optgroup")}}, {{htmlelement("label")}}, {{htmlelement("button")}}, {{htmlelement("selectedcontent")}}
+- {{cssxref("appearance")}}
+- {{cssxref("::picker()", "::picker(select)")}}, {{cssxref("::picker-icon")}}, {{cssxref("::checkmark")}}
+- {{cssxref(":open")}}, {{cssxref(":checked")}}

From 029cb9dbf22eb1e45e5ad6f6513a7212ef76e10c Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Fri, 7 Mar 2025 10:56:59 +0000
Subject: [PATCH 04/15] correct info about how <selectedcontent> is populated

---
 .../extensions/forms/customizable_select/index.md           | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 55084597f8b22d8..70c45ac6777b1dd 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -25,7 +25,7 @@ You'll find out how to build this example in the sections below.
 You can build customizable `<select>` elements using the following HTML and CSS features:
 
 - Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be easily designed to fall back to classic selects in non-supporting browsers.
-- The {{htmlelement("selectedcontent")}} element, which under the hood provides a {{htmlelement("slot")}} into which is placed the contents of the currently-selected `<option>`. This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}**, as it is the button you need to press to open the drop-down menu.
+- The {{htmlelement("selectedcontent")}} element, which contains a clone of the currently-selected `<option>` (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
 - The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`.
 - The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
 - The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
@@ -82,7 +82,7 @@ Our example is a typical {{htmlelement("select")}} menu that allows you to choos
 
 This is nearly the same as "classic" `<select>` markup, with the following differences:
 
-- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element provides a {{htmlelement("slot")}} into which is placed the contents of the currently-selected {{htmlelement("option")}}. This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fill in the selected value inside the select button implicitly, but you won't be able to select it using CSS.
+- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fill in the selected value inside the select button implicitly, but you won't be able to select it using CSS.
 - The rest of the `<select>` contents represents the picker (the `<select>` drop-down menu). This obviously includes the `<option>` elements representing the different choices in the picker, but you can also include other content if desired.
 - Traditionally, `<option>` elements could only contain text, but in a customizable select you can include markup structures including images and more besides. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
 
@@ -258,7 +258,7 @@ Our example now renders like this:
 
 If you select any pet option from the last few live examples, you'll notice a problem — the pet icons cause the select `<button>` to increase in height, which also changes the position of the picker icon, and there is no spacing between the option icon and label — not a great look.
 
-This can be fixed by hiding the icon when it is contained inside the `<selectedcontent>` slot, which represents the contents of the selected `<option>` as they appear inside the select `<button>`. In our example, it is hidden using {{cssxref("display", "display: none")}}:
+This can be fixed by hiding the icon when it is contained inside `<selectedcontent>`, which represents the contents of the selected `<option>` as they appear inside the select `<button>`. In our example, it is hidden using {{cssxref("display", "display: none")}}:
 
 ```css live-sample___fourth-render live-sample___full-render
 selectedcontent .icon {

From 80b9f67965261b6ee8f6ed8367fb2b62da043d16 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Fri, 7 Mar 2025 13:14:02 +0000
Subject: [PATCH 05/15] add links to customizable select guide, update existing
 pages, remove unneeded links

---
 .../forms/advanced_form_styling/index.md      | 14 ++++++++-----
 .../forms/basic_native_form_controls/index.md |  5 -----
 .../forms/customizable_select/index.md        |  2 +-
 .../extensions/forms/form_validation/index.md |  5 -----
 .../index.md                                  | 21 -------------------
 .../how_to_structure_a_web_form/index.md      |  5 -----
 .../forms/html5_input_types/index.md          |  5 -----
 .../html_forms_in_legacy_browsers/index.md    | 21 -------------------
 .../extensions/forms/index.md                 |  4 +++-
 .../forms/other_form_controls/index.md        |  5 -----
 .../sending_and_retrieving_form_data/index.md |  5 -----
 .../sending_forms_through_javascript/index.md | 21 -------------------
 .../forms/styling_web_forms/index.md          |  7 ++-----
 .../forms/ui_pseudo-classes/index.md          |  5 -----
 .../extensions/forms/your_first_form/index.md |  5 -----
 .../en-us/web/html/element/optgroup/index.md  |  1 +
 files/en-us/web/html/element/option/index.md  | 13 ++++++++----
 files/en-us/web/html/element/select/index.md  | 15 ++++++++-----
 18 files changed, 35 insertions(+), 124 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md b/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
index 40860c7621de1d6..27259086fa5c60f 100644
--- a/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
@@ -38,6 +38,8 @@ To recap what we said in the previous article, we have:
 **The ugly**: Some elements can't be styled thoroughly using CSS. These include:
 
 - Elements involved in creating dropdown widgets, including {{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}} and {{HTMLElement("datalist")}}.
+  > [!NOTE]
+  > Many modern browsers now support [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), a set of HTML and CSS features that together enable full customization of `<select>` elements and their contents just like any regular DOM elements.
 - [`<input type="color">`](/en-US/docs/Web/HTML/Element/input/color)
 - Date-related controls such as [`<input type="datetime-local">`](/en-US/docs/Web/HTML/Element/input/datetime-local)
 - [`<input type="range">`](/en-US/docs/Web/HTML/Element/input/range)
@@ -367,9 +369,11 @@ Let's talk about some specifics of each of these types of control, highlighting
 
 ### Selects and datalists
 
-In modern browsers, selects and datalists are generally not too bad to style provided you don't want to vary the look and feel too much from the defaults.
+Selects and datalists are generally not too bad to style.
 
-We've managed to get the basic look of the boxes looking pretty uniform and consistent. The datalist control is `<input type="text">` anyway, so we knew this wouldn't be a problem.
+Many modern browsers now support [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), a set of HTML and CSS features that together enable full customization of `<select>` elements and their contents just like any regular DOM elements. In supporting browsers and codebases, you don't need to worry about these legacy techniques any more.
+
+Even in non-supporting browsers and codebases, you can get a reasonable level of customization provided you don't want to vary the look and feel too much from the defaults. We've managed to get the basic look of the boxes looking pretty uniform and consistent. The datalist control is `<input type="text">` anyway, so we knew this wouldn't be a problem.
 
 Two things are slightly more problematic. First of all, the select's "arrow" icon that indicates it is a dropdown differs across browsers. It also tends to change if you increase the size of the select box, or resize in an ugly fashion. To fix this in our example we first used our old friend `appearance: none` to get rid of the icon altogether:
 
@@ -518,7 +522,7 @@ In the next article of this module, we will explore the different [UI pseudo-cla
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/Styling_web_forms", "Learn_web_development/Extensions/Forms/UI_pseudo-classes", "Learn_web_development/Extensions/Forms")}}
 
-### Advanced Topics
+## See also
 
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
+  - : This article explains how to use dedicated, modern HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements.
diff --git a/files/en-us/learn_web_development/extensions/forms/basic_native_form_controls/index.md b/files/en-us/learn_web_development/extensions/forms/basic_native_form_controls/index.md
index 89a36da4592a7e0..672e7bb2c7b4af8 100644
--- a/files/en-us/learn_web_development/extensions/forms/basic_native_form_controls/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/basic_native_form_controls/index.md
@@ -415,8 +415,3 @@ You've reached the end of this article, but can you remember the most important
 This article has covered the older input types — the original set introduced in the early days of HTML that is well-supported in all browsers. In the next section, we'll take a look at the more modern values of the `type` attribute.
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/How_to_structure_a_web_form", "Learn_web_development/Extensions/Forms/HTML5_input_types", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 70c45ac6777b1dd..65f15399adbfb0e 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -6,7 +6,7 @@ page-type: learn-module-chapter
 
 {{LearnSidebar}}
 
-This article explains how to use a number of HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements. This includes having full control over styling the select button, drop-down picker, arrow icon, checkbox to indicate which item is currently selected, each individual {{htmlelement("option")}} element, and more besides.
+This article explains how to use dedicated, modern HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements. This includes having full control over styling the select button, drop-down picker, arrow icon, checkbox to indicate which item is currently selected, each individual {{htmlelement("option")}} element, and more besides.
 
 ## Background
 
diff --git a/files/en-us/learn_web_development/extensions/forms/form_validation/index.md b/files/en-us/learn_web_development/extensions/forms/form_validation/index.md
index 67aac474fec048c..d3e609ab353f0c0 100644
--- a/files/en-us/learn_web_development/extensions/forms/form_validation/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/form_validation/index.md
@@ -867,8 +867,3 @@ Once you have checked that the form is filled out correctly, the form can be sub
 We'll cover [sending form data](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data) next.
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/UI_pseudo-classes", "Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/how_to_build_custom_form_controls/index.md b/files/en-us/learn_web_development/extensions/forms/how_to_build_custom_form_controls/index.md
index 8559f9ec9d22b59..874a7d7b19a84be 100644
--- a/files/en-us/learn_web_development/extensions/forms/how_to_build_custom_form_controls/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/how_to_build_custom_form_controls/index.md
@@ -2095,24 +2095,3 @@ Here are a few libraries you should consider before coding your own:
 - [msDropDown](https://github.com/marghoobsuleman/ms-Dropdown)
 
 If you do create alternative controls via radio buttons, your own JavaScript, or with a 3rd party library, ensure it is accessible and feature-proof; that is, it needs to be able to work better with a variety of browsers whose compatibility with the Web standards they use vary. Have fun!
-
-## See also
-
-### Learning path
-
-- [Your first HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/Your_first_form)
-- [How to structure an HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_structure_a_web_form)
-- [The native form controls](/en-US/docs/Learn_web_development/Extensions/Forms/Basic_native_form_controls)
-- [HTML5 input types](/en-US/docs/Learn_web_development/Extensions/Forms/HTML5_input_types)
-- [Additional form controls](/en-US/docs/Learn_web_development/Extensions/Forms/Other_form_controls)
-- [UI pseudo-classes](/en-US/docs/Learn_web_development/Extensions/Forms/UI_pseudo-classes)
-- [Styling HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Styling_web_forms)
-- [Form data validation](/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation)
-- [Sending form data](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data)
-
-### Advanced Topics
-
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
-- **How to build custom form controls**
-- [HTML forms in legacy browsers](/en-US/docs/Learn_web_development/Extensions/Forms/HTML_forms_in_legacy_browsers)
-- [Advanced styling for HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling)
diff --git a/files/en-us/learn_web_development/extensions/forms/how_to_structure_a_web_form/index.md b/files/en-us/learn_web_development/extensions/forms/how_to_structure_a_web_form/index.md
index 1530885779c78c1..de25f962d283394 100644
--- a/files/en-us/learn_web_development/extensions/forms/how_to_structure_a_web_form/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/how_to_structure_a_web_form/index.md
@@ -403,8 +403,3 @@ You now have all the knowledge you'll need to properly structure your web forms.
 - [A List Apart: _Sensible Forms: A Form Usability Checklist_](https://alistapart.com/article/sensibleforms/)
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/Your_first_form", "Learn_web_development/Extensions/Forms/Basic_native_form_controls", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/html5_input_types/index.md b/files/en-us/learn_web_development/extensions/forms/html5_input_types/index.md
index c7999df44eb2f1f..381d437552987ee 100644
--- a/files/en-us/learn_web_development/extensions/forms/html5_input_types/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/html5_input_types/index.md
@@ -380,8 +380,3 @@ You've reached the end of this article, but can you remember the most important
 That brings us to the end of our tour of the HTML5 form input types. There are a few other control types that cannot be easily grouped due to their very specific behaviors but are still essential to know. We cover those in the next article.
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/Basic_native_form_controls", "Learn_web_development/Extensions/Forms/Other_form_controls", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/html_forms_in_legacy_browsers/index.md b/files/en-us/learn_web_development/extensions/forms/html_forms_in_legacy_browsers/index.md
index de0109977a950af..5dc87fd3ec6b24c 100644
--- a/files/en-us/learn_web_development/extensions/forms/html_forms_in_legacy_browsers/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/html_forms_in_legacy_browsers/index.md
@@ -143,24 +143,3 @@ Even though some polyfills are very aware of performance, loading additional scr
 As you can see, considering browser and operating system default form control appearance is important. There are many techniques to handle these issue; however mastering all of them is beyond the scope of this article. The basic premise is to consider whether altering the default implementation is worth the work before embarking on the challenge.
 
 If you read all the articles of this [HTML Forms guide](/en-US/docs/Learn_web_development/Extensions/Forms), you should now be at ease with using forms. If you discover new techniques or hints, please help improve the guide.
-
-## See also
-
-### Learning path
-
-- [Your first HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/Your_first_form)
-- [How to structure an HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_structure_a_web_form)
-- [The native form widgets](/en-US/docs/Learn_web_development/Extensions/Forms/Basic_native_form_controls)
-- [HTML5 input types](/en-US/docs/Learn_web_development/Extensions/Forms/HTML5_input_types)
-- [Additional form controls](/en-US/docs/Learn_web_development/Extensions/Forms/Other_form_controls)
-- [UI pseudo-classes](/en-US/docs/Learn_web_development/Extensions/Forms/UI_pseudo-classes)
-- [Styling HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Styling_web_forms)
-- [Form data validation](/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation)
-- [Sending form data](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data)
-
-### Advanced Topics
-
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
-- [How to build custom form widgets](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- **HTML forms in legacy browsers**
-- [Advanced styling for HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling)
diff --git a/files/en-us/learn_web_development/extensions/forms/index.md b/files/en-us/learn_web_development/extensions/forms/index.md
index 96c211641f3be51..9a6bcfdd2cb565e 100644
--- a/files/en-us/learn_web_development/extensions/forms/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/index.md
@@ -53,7 +53,7 @@ The above text is a good indicator as to why we've put web forms into its own st
 - [Sending form data](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data)
   - : This article looks at what happens when a user submits a form — where does the data go, and how do we handle it when it gets there? We also look at some of the security concerns associated with sending form data.
 
-## Advanced articles
+## Additional articles
 
 The following articles aren't included in the learning pathway, but they'll prove interesting and useful when you've mastered the above techniques and want to know more.
 
@@ -61,6 +61,8 @@ The following articles aren't included in the learning pathway, but they'll prov
   - : You'll come across some cases where the native form widgets just don't provide what you need, e.g. because of styling or functionality. In such cases, you may need to build your own form widget out of raw HTML. This article explains how you'd do this and the considerations you need to be aware of when doing so, with a practical case study.
 - [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
   - : This article looks at ways to use a form to assemble an HTTP request and send it via custom JavaScript, rather than standard form submission. It also looks at why you'd want to do this, and the implications of doing so. (See also [Using FormData objects](/en-US/docs/Web/API/XMLHttpRequest_API/Using_FormData_Objects).)
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
+  - : This article explains how to use dedicated, modern HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements.
 
 ## See also
 
diff --git a/files/en-us/learn_web_development/extensions/forms/other_form_controls/index.md b/files/en-us/learn_web_development/extensions/forms/other_form_controls/index.md
index 929bfca1c1cebd6..886cb61bb4c7ed3 100644
--- a/files/en-us/learn_web_development/extensions/forms/other_form_controls/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/other_form_controls/index.md
@@ -272,8 +272,3 @@ As you'll have seen in the last few articles, there are many types of form contr
 Now that you have a grasp of the HTML behind the different available form controls, we'll take a look at [Styling them](/en-US/docs/Learn_web_development/Extensions/Forms/Styling_web_forms).
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/HTML5_input_types","Learn_web_development/Extensions/Forms/Styling_web_forms", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/sending_and_retrieving_form_data/index.md b/files/en-us/learn_web_development/extensions/forms/sending_and_retrieving_form_data/index.md
index b3ccc1bc0a4ced0..4af795964ab014f 100644
--- a/files/en-us/learn_web_development/extensions/forms/sending_and_retrieving_form_data/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/sending_and_retrieving_form_data/index.md
@@ -338,8 +338,3 @@ If you want to learn more about securing a web application, you can dig into the
 - [Web Security by Mozilla](https://infosec.mozilla.org/guidelines/web_security)
 
 {{PreviousMenu("Learn_web_development/Extensions/Forms/Form_validation", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/sending_forms_through_javascript/index.md b/files/en-us/learn_web_development/extensions/forms/sending_forms_through_javascript/index.md
index 871297bbcdd2932..2080849af694f02 100644
--- a/files/en-us/learn_web_development/extensions/forms/sending_forms_through_javascript/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/sending_forms_through_javascript/index.md
@@ -122,24 +122,3 @@ form.addEventListener("submit", (event) => {
 We add a submit event handler for the form element. This first calls {{domxref("Event.preventDefault()", "preventDefault()")}} to prevent the browser's built-in form submission, so we can take over. Then we call `sendData()`, which retrieves the form element and passes it into the `FormData` constructor.
 
 After that, we send the `FormData` instance as an HTTP `POST` request, using `fetch()`.
-
-## See also
-
-### Learning path
-
-- [Your first HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/Your_first_form)
-- [How to structure an HTML form](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_structure_a_web_form)
-- [The native form widgets](/en-US/docs/Learn_web_development/Extensions/Forms/Basic_native_form_controls)
-- [HTML5 input types](/en-US/docs/Learn_web_development/Extensions/Forms/HTML5_input_types)
-- [Additional form controls](/en-US/docs/Learn_web_development/Extensions/Forms/Other_form_controls)
-- [UI pseudo-classes](/en-US/docs/Learn_web_development/Extensions/Forms/UI_pseudo-classes)
-- [Styling HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Styling_web_forms)
-- [Form data validation](/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation)
-- [Sending form data](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_and_retrieving_form_data)
-
-### Advanced Topics
-
-- **Sending forms through JavaScript**
-- [How to build custom form widgets](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [HTML forms in legacy browsers](/en-US/docs/Learn_web_development/Extensions/Forms/HTML_forms_in_legacy_browsers)
-- [Advanced styling for HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling)
diff --git a/files/en-us/learn_web_development/extensions/forms/styling_web_forms/index.md b/files/en-us/learn_web_development/extensions/forms/styling_web_forms/index.md
index 26493b32f41e675..92721a0cdddde8e 100644
--- a/files/en-us/learn_web_development/extensions/forms/styling_web_forms/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/styling_web_forms/index.md
@@ -62,6 +62,8 @@ The article [Advanced form styling](/en-US/docs/Learn_web_development/Extensions
 - [`<input type="range">`](/en-US/docs/Web/HTML/Element/input/range)
 - [`<input type="file">`](/en-US/docs/Web/HTML/Element/input/file)
 - Elements involved in creating dropdown widgets, including {{HTMLElement("select")}}, {{HTMLElement("option")}}, {{HTMLElement("optgroup")}} and {{HTMLElement("datalist")}}.
+  > [!NOTE]
+  > Many modern browsers now support [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), a set of HTML and CSS features that together enable full customization of `<select>` elements and their contents just like any regular DOM elements.
 - {{HTMLElement("progress")}} and {{HTMLElement("meter")}}
 
 For example, the date picker calendar, and the button on \<select> that displays an options list when clicked, can't be styled using CSS alone.
@@ -382,8 +384,3 @@ You've reached the end of this article, but can you remember the most important
 As you can see, as long as we want to build forms with just text fields and buttons, it's easy to style them using CSS. [In the next article](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling), we will see how to handle form widgets which fall into the "bad" and "ugly" categories.
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/Other_form_controls","Learn_web_development/Extensions/Forms/Advanced_form_styling","Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/ui_pseudo-classes/index.md b/files/en-us/learn_web_development/extensions/forms/ui_pseudo-classes/index.md
index d99a25a0c77d2c0..a7dd39af925d8cd 100644
--- a/files/en-us/learn_web_development/extensions/forms/ui_pseudo-classes/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/ui_pseudo-classes/index.md
@@ -611,8 +611,3 @@ You've reached the end of this article, but can you remember the most important
 This completes our look at UI pseudo-classes that relate to form inputs. Keep playing with them, and create some fun form styles! Next up, we'll move on to something different — [client-side form validation](/en-US/docs/Learn_web_development/Extensions/Forms/Form_validation).
 
 {{PreviousMenuNext("Learn_web_development/Extensions/Forms/Advanced_form_styling", "Learn_web_development/Extensions/Forms/Form_validation", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/learn_web_development/extensions/forms/your_first_form/index.md b/files/en-us/learn_web_development/extensions/forms/your_first_form/index.md
index 3c60effcd13ab9c..48e18206e00e6e4 100644
--- a/files/en-us/learn_web_development/extensions/forms/your_first_form/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/your_first_form/index.md
@@ -395,8 +395,3 @@ button {
 That's only the beginning, however — now it's time to take a deeper look. Forms have way more power than what we saw here and the other articles in this module will help you to master the rest.
 
 {{NextMenu("Learn_web_development/Extensions/Forms/How_to_structure_a_web_form", "Learn_web_development/Extensions/Forms")}}
-
-### Advanced Topics
-
-- [How to build custom form controls](/en-US/docs/Learn_web_development/Extensions/Forms/How_to_build_custom_form_controls)
-- [Sending forms through JavaScript](/en-US/docs/Learn_web_development/Extensions/Forms/Sending_forms_through_JavaScript)
diff --git a/files/en-us/web/html/element/optgroup/index.md b/files/en-us/web/html/element/optgroup/index.md
index 5ecd49f67e9c0cf..de9a2d995bc4194 100644
--- a/files/en-us/web/html/element/optgroup/index.md
+++ b/files/en-us/web/html/element/optgroup/index.md
@@ -123,3 +123,4 @@ This element includes the [global attributes](/en-US/docs/Web/HTML/Global_attrib
 ## See also
 
 - Other form-related elements: {{HTMLElement("form")}}, {{HTMLElement("legend")}}, {{HTMLElement("label")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}}, {{HTMLElement("datalist")}}, {{HTMLElement("option")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("textarea")}}, {{HTMLElement("input")}}, {{HTMLElement("output")}}, {{HTMLElement("progress")}} and {{HTMLElement("meter")}}.
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/html/element/option/index.md b/files/en-us/web/html/element/option/index.md
index 83dd841433ad243..30aa22390ab7aad 100644
--- a/files/en-us/web/html/element/option/index.md
+++ b/files/en-us/web/html/element/option/index.md
@@ -53,9 +53,13 @@ This element includes the [global attributes](/en-US/docs/Web/HTML/Global_attrib
 
 ## Styling with CSS
 
-Styling the **`<option>`** element inside a `<select>` dropdown is highly limited and depends on the browser and operating system. Depending on the operating system, the [`font-size`](/en-US/docs/Web/CSS/font-size) of the owning `<select>` is respected in Firefox and Chromium. Chromium may additionally allow [`color`](/en-US/docs/Web/CSS/color), [`background-color`](/en-US/docs/Web/CSS/background-color), [`font-family`](/en-US/docs/Web/CSS/font-family), [`font-variant`](/en-US/docs/Web/CSS/font-variant), and [`text-align`](/en-US/docs/Web/CSS/text-align) to be set.
+Styling `<option>` elements has historically been highly limited, hence features being introduced to enable their full customization, just like any regular DOM element. See [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) for more details.
 
-You can find more details about styling `<option>` in [our guide to advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
+### Legacy option styling
+
+In browsers that don't support the modern customization features (or legacy codebases where they can't be used), the styling available on `<option>` elements depends on the browser and operating system. Depending on the operating system, the [`font-size`](/en-US/docs/Web/CSS/font-size) of the owning `<select>` is respected in Firefox and Chromium. Chromium may additionally allow [`color`](/en-US/docs/Web/CSS/color), [`background-color`](/en-US/docs/Web/CSS/background-color), [`font-family`](/en-US/docs/Web/CSS/font-family), [`font-variant`](/en-US/docs/Web/CSS/font-variant), and [`text-align`](/en-US/docs/Web/CSS/text-align) to be set.
+
+You can find more details about legacy `<option>` styling in [our guide to advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
 
 ## Examples
 
@@ -76,8 +80,8 @@ See {{HTMLElement("select")}} for examples.
     <tr>
       <th scope="row">Permitted content</th>
       <td>
-        Text, possibly with escaped characters (like
-        <code>&#x26;eacute;</code>).
+        In traditional <code>&lt;select&gt;</code> elements, only text content is permitted, possibly with escaped characters (like
+        <code>&#x26;eacute;</code>). In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>, <code>&lt;option&gt;</code> elements can have any arbitrary content.
       </td>
     </tr>
     <tr>
@@ -123,3 +127,4 @@ See {{HTMLElement("select")}} for examples.
 ## See also
 
 - Other form-related elements: {{HTMLElement("form")}}, {{HTMLElement("legend")}}, {{HTMLElement("label")}}, {{HTMLElement("button")}}, {{HTMLElement("select")}}, {{HTMLElement("datalist")}}, {{HTMLElement("optgroup")}}, {{HTMLElement("fieldset")}}, {{HTMLElement("textarea")}}, {{HTMLElement("input")}}, {{HTMLElement("output")}}, {{HTMLElement("progress")}} and {{HTMLElement("meter")}}.
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/html/element/select/index.md b/files/en-us/web/html/element/select/index.md
index a059352e850c6a3..d0b87699a180e2d 100644
--- a/files/en-us/web/html/element/select/index.md
+++ b/files/en-us/web/html/element/select/index.md
@@ -106,13 +106,17 @@ Keyboard users can select multiple non-contiguous items by:
 
 ## Styling with CSS
 
-The `<select>` element is notoriously difficult to style productively with CSS. You can affect certain aspects like any element — for example, manipulating the [box model](/en-US/docs/Learn_web_development/Core/Styling_basics/Box_model), the [displayed font](/en-US/docs/Web/CSS/CSS_fonts), etc., and you can use the {{cssxref("appearance")}} property to remove the default system `appearance`.
+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).
 
-However, these properties don't produce a consistent result across browsers, and it is hard to do things like line different types of form element up with one another in a column. The `<select>` element's internal structure is complex, and hard to control. If you want to get full control, you should consider using a library with good facilities for styling form widgets, or try rolling your own dropdown menu using non-semantic elements, JavaScript, and [WAI-ARIA](/en-US/docs/Learn_web_development/Core/Accessibility/WAI-ARIA_basics) to provide semantics.
+### Legacy select styling
 
-You can also use the {{cssxref(":open")}} pseudo-class to style a `<select>` element when it is in the open state, that is, when the drop-down options list is displayed. This doesn't apply to multi-line `<select>` elements (those with the [`multiple`](/en-US/docs/Web/HTML/Attributes/multiple) attribute set) — they tend to render as a scrolling list box rather than a drop-down, so don't have an open state.
+In browsers that don't support the modern customization features (or legacy codebases where they can't be used), you are limited to manipulating the [box model](/en-US/docs/Learn_web_development/Core/Styling_basics/Box_model), the [displayed font](/en-US/docs/Web/CSS/CSS_fonts), etc. You can also use the {{cssxref("appearance")}} property to remove the default system `appearance`.
 
-For more useful information on styling `<select>`, see:
+It is however, hard to get a consistent result across browsers with traditional `<select>` elements. If you want to get full control, you should consider using a library with good facilities for styling form widgets, or try rolling your own dropdown menu using non-semantic elements, JavaScript, and [WAI-ARIA](/en-US/docs/Learn_web_development/Core/Accessibility/WAI-ARIA_basics) to provide semantics.
+
+You can use the {{cssxref(":open")}} pseudo-class to style `<select>` elements in the open state, that is, when the drop-down options list is displayed. This doesn't apply to multi-line `<select>` elements (those with the [`multiple`](/en-US/docs/Web/HTML/Attributes/multiple) attribute set) — they tend to render as a scrolling list box rather than a drop-down, so don't have an open state.
+
+For more information on legacy `<select>` styling, see:
 
 - [Styling HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Styling_web_forms)
 - [Advanced styling for HTML forms](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling)
@@ -258,7 +262,7 @@ You'll see that:
       <th scope="row">Permitted content</th>
       <td>
         Zero or more {{HTMLElement("option")}},
-        {{HTMLElement("optgroup")}} or {{HTMLElement("hr")}} elements.
+        {{HTMLElement("optgroup")}}, or {{HTMLElement("hr")}} elements in traditional <code>&lt;select&gt;</code> elements. In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>, the select {{htmlelement("button")}} is optionally included as a child <code>&lt;button&gt;</code> element with a nested {{htmlelement("selectedcontent")}} element, and the picker is defined as any other arbitrary content including zero or more <code>&lt;option&gt;</code>, <code>&lt;optgroup&gt;</code>, or <code>&lt;hr&gt;</code> elements.
       </td>
     </tr>
     <tr>
@@ -312,3 +316,4 @@ You'll see that:
 - Events fired by `<select>`: {{domxref("HTMLElement/change_event", "change")}}, {{domxref("Element/input_event", "input")}}
 - The {{HTMLElement("option")}} element
 - The {{HTMLElement("optgroup")}} element
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)

From 9998430c1cf451a7d142a7463c1d0648be775b23 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Fri, 7 Mar 2025 15:11:50 +0000
Subject: [PATCH 06/15] Document selectedcontent element

---
 .../forms/customizable_select/index.md        |   4 +-
 .../api/htmlselectedcontentelement/index.md   |  32 +++++
 files/en-us/web/html/element/button/index.md  |   3 +-
 .../web/html/element/selectedcontent/index.md | 119 ++++++++++++++++++
 4 files changed, 155 insertions(+), 3 deletions(-)
 create mode 100644 files/en-us/web/api/htmlselectedcontentelement/index.md
 create mode 100644 files/en-us/web/html/element/selectedcontent/index.md

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 65f15399adbfb0e..1d65e0f80cf5e2f 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -25,7 +25,7 @@ You'll find out how to build this example in the sections below.
 You can build customizable `<select>` elements using the following HTML and CSS features:
 
 - Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be easily designed to fall back to classic selects in non-supporting browsers.
-- The {{htmlelement("selectedcontent")}} element, which contains a clone of the currently-selected `<option>` (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
+- The {{htmlelement("selectedcontent")}} element, which contains a clone of the currently-selected `<option>` element's content (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
 - The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`.
 - The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
 - The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
@@ -82,7 +82,7 @@ Our example is a typical {{htmlelement("select")}} menu that allows you to choos
 
 This is nearly the same as "classic" `<select>` markup, with the following differences:
 
-- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fill in the selected value inside the select button implicitly, but you won't be able to select it using CSS.
+- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will place the selected option content inside the select button implicitly, but you won't be able to select it using CSS.
 - The rest of the `<select>` contents represents the picker (the `<select>` drop-down menu). This obviously includes the `<option>` elements representing the different choices in the picker, but you can also include other content if desired.
 - Traditionally, `<option>` elements could only contain text, but in a customizable select you can include markup structures including images and more besides. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
 
diff --git a/files/en-us/web/api/htmlselectedcontentelement/index.md b/files/en-us/web/api/htmlselectedcontentelement/index.md
new file mode 100644
index 000000000000000..352dedd6ee383b3
--- /dev/null
+++ b/files/en-us/web/api/htmlselectedcontentelement/index.md
@@ -0,0 +1,32 @@
+---
+title: HTMLSelectedContentElement
+slug: Web/API/HTMLSelectedContentElement
+page-type: web-api-interface
+browser-compat: api.HTMLSelectedContentElement
+---
+
+{{APIRef("HTML DOM")}}
+
+The **`HTMLSelectedContentElement`** interface represents a {{HTMLElement("selectedcontent")}} element in the [DOM](/en-US/docs/Web/API/Document_Object_Model).
+
+{{InheritanceDiagram}}
+
+## Instance properties
+
+_This interface has no properties, but inherits properties from: {{DOMxRef("HTMLElement")}}._
+
+## Instance methods
+
+_This interface has no methods, but inherits methods from: {{DOMxRef("HTMLElement")}}._
+
+## Specifications
+
+{{Specifications}}
+
+## Browser compatibility
+
+{{Compat}}
+
+## See also
+
+- The HTML element implementing this interface: {{HTMLElement("selectedcontent")}}.
diff --git a/files/en-us/web/html/element/button/index.md b/files/en-us/web/html/element/button/index.md
index edaa764515f7276..98d392d0641a6e0 100644
--- a/files/en-us/web/html/element/button/index.md
+++ b/files/en-us/web/html/element/button/index.md
@@ -294,7 +294,8 @@ Whether clicking on a `<button>` or {{HTMLElement("input")}} button types causes
         <a
           href="/en-US/docs/Web/HTML/Content_categories#interactive_content"
           >Interactive content</a
-        >
+        >. If the <code>&lt;button&gt;</code> is the first child of a <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select element</a>, then it may also
+   contain zero or one {{htmlelement("selectedcontent")}} element.
       </td>
     </tr>
     <tr>
diff --git a/files/en-us/web/html/element/selectedcontent/index.md b/files/en-us/web/html/element/selectedcontent/index.md
new file mode 100644
index 000000000000000..62373cffc0a6a64
--- /dev/null
+++ b/files/en-us/web/html/element/selectedcontent/index.md
@@ -0,0 +1,119 @@
+---
+title: "<selectedcontent>: The selected option display element"
+slug: Web/HTML/Element/selectedcontent
+page-type: html-element
+browser-compat: html.elements.selectedcontent
+---
+
+{{HTMLSidebar}}
+
+The **`<selectedcontent>`** [HTML](/en-US/docs/Web/HTML) element contains a clone of a {{htmlelement("select")}} element's currently-selected {{htmlelement("option")}} element content, created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood. `<selectedcontent>` represents the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}** as it is the button you need to press to open the drop-down picker.
+
+## Attributes
+
+This element includes the [global attributes](/en-US/docs/Web/HTML/Global_attributes), but has no other attributes defined on it.
+
+## Description
+
+When creating a [Customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), you can include the `<selectedcontent>` element inside a {{htmlelement("button")}} element, which in turn needs to be the first child of the `<select>` element:
+
+```html
+<select>
+  <button>
+    <selectedcontent></selectedcontent>
+  </button>
+
+  ...
+</select>
+```
+
+Any subsequent `<select>` content will be included in the drop-down picker.
+
+Whenever the `<select>` element's selected `<option>` switches from one option to another, the `<selectedcontent>` element's content is removed and replaced by a new cloned copy of the DOM structure of the newly selected <code>option</code>, which is created using {{domxref("Node.cloneNode", "cloneNode()")}}.
+
+## Styling with CSS
+
+It is useful to be able to target the currently-selected `<option>` element's content as it appears inside the select `<button>` with CSS styles, without affecting the styling of the content as it appears inside the picker.
+
+For example, your `<option>` elements may contain icons, images, or even videos. This content might look nice inside the picker, but could cause the select `<button>` to increase in size, look untidy, and affect the surrounding layout.
+
+This can be fixed by hiding the problem content when it is contained inside `<selectedcontent>`. For example:
+
+```css
+selectedcontent img {
+  display: none;
+}
+```
+
+> [!NOTE]
+> If the `<button>` and/or `<selectedcontent>` elements are not included inside the `<select>` markup, the browser will place the selected option content inside the select `<button>` implicitly, but this targetting will not be possible.
+
+## Examples
+
+You can see a full example that includes the `<selectedcontent>` element in our [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) guide.
+
+## Technical summary
+
+<table class="properties">
+  <tbody>
+    <tr>
+      <th scope="row">
+        <a href="/en-US/docs/Web/HTML/Content_categories"
+          >Content categories</a
+        >
+      </th>
+      <td>
+        <a href="/en-US/docs/Web/HTML/Content_categories#form-associated_"
+          >form-associated </a
+        >element.
+      </td>
+    </tr>
+    <tr>
+      <th scope="row">Permitted content</th>
+      <td>
+        Mirrors content from the selected {{htmlelement("option")}}.
+      </td>
+    </tr>
+    <tr>
+      <th scope="row">Tag omission</th>
+      <td>None, both the starting and ending tag are mandatory.</td>
+    </tr>
+    <tr>
+      <th scope="row">Permitted parents</th>
+      <td>
+        A {{htmlelement("button")}} element that is the first child of a {{htmlelement("select")}} element.
+      </td>
+    </tr>
+    <tr>
+      <th scope="row">Implicit ARIA role</th>
+      <td>
+        None
+      </td>
+    </tr>
+    <tr>
+      <th scope="row">Permitted ARIA roles</th>
+      <td>
+        None
+      </td>
+    </tr>
+    <tr>
+      <th scope="row">DOM interface</th>
+      <td>{{domxref("HTMLSelectedContentElement")}}</td>
+    </tr>
+  </tbody>
+</table>
+
+## Specifications
+
+{{Specifications}}
+
+## Browser compatibility
+
+{{Compat}}
+
+## See also
+
+- The {{HTMLElement("select")}} element
+- The {{HTMLElement("option")}} element
+- The {{HTMLElement("optgroup")}} element
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)

From 4dc30406d1d381d0e7b510f604e4451dbe831271 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Mon, 10 Mar 2025 10:20:43 +0000
Subject: [PATCH 07/15] Add doc for ::picker()

---
 .../forms/customizable_select/index.md        |  2 +-
 .../web/css/_doublecolon_picker/index.md      | 70 +++++++++++++++++++
 files/en-us/web/css/pseudo-elements/index.md  |  3 +
 .../web/html/element/selectedcontent/index.md |  4 +-
 4 files changed, 75 insertions(+), 4 deletions(-)
 create mode 100644 files/en-us/web/css/_doublecolon_picker/index.md

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 1d65e0f80cf5e2f..ddf65e42bc926c0 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -186,7 +186,7 @@ Let's have a look at the work so far — note how the picker arrow rotates smoot
 
 The select picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As mentioned earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
 
-First of all, the picker's default black {{cssxref("border")}} border is removed:
+First of all, the picker's default black {{cssxref("border")}} is removed:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 ::picker(select) {
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
new file mode 100644
index 000000000000000..c9de8647a95a8fe
--- /dev/null
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -0,0 +1,70 @@
+---
+title: ::picker()
+slug: Web/CSS/::picker
+page-type: css-pseudo-element
+browser-compat: css.selectors.picker
+---
+
+{{CSSRef}}
+
+The **`::picker()`** [CSS](/en-US/docs/Web/CSS) [pseudo-element](/en-US/docs/Web/CSS/Pseudo-elements) represents the picker part of an element, for example the drop-down picker of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select).
+
+## Syntax
+
+```css-nolint
+::picker(<ident>) {
+  /* ... */
+}
+```
+
+### Parameters
+
+- {{cssxref("ident")}}
+  - : A string representing the element whose picker you want to target. The following values are available:
+    - `select`
+      - : The drop-down picker of customizable select elements.
+
+## Description
+
+The `::picker()` pseudo-element targets the picker part of a form control, that is, the pop-up part that appears to allow you to make a selection when you press the control button.
+
+The `::picker(select)` selector targets all descendants of customizable `<select>` element except for the first `<button>` child; these decendants are grouped together by the browser and rendered as the picker. The first `<button>` child represents the control button that opens the picker when pressed.
+
+This allows you to target all of the picker contents as a single entity, for example if you want to customize its border, animate it when it appears and disappears, or position it somewhere different to the default position. Our [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) guide shows many examples of `::picker(select)` usage.
+
+## Examples
+
+### Basic custom select usage
+
+To opt-in to custom select functionality, your `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+
+```css
+select,
+::picker(select) {
+  appearance: base-select;
+}
+```
+
+You could then, for example, remove the picker's default black {{cssxref("border")}}:
+
+```css
+::picker(select) {
+  border: none;
+}
+```
+
+## Specifications
+
+{{Specifications}}
+
+## Browser compatibility
+
+{{Compat}}
+
+## See also
+
+- {{htmlelement("select")}}, {{htmlelement("option")}}, {{htmlelement("optgroup")}}, {{htmlelement("label")}}, {{htmlelement("button")}}, {{htmlelement("selectedcontent")}}
+- {{cssxref("appearance")}}
+- {{cssxref("::picker-icon")}}, {{cssxref("::checkmark")}}
+- {{cssxref(":open")}}, {{cssxref(":checked")}}
+- [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/css/pseudo-elements/index.md b/files/en-us/web/css/pseudo-elements/index.md
index 7d7fc2efb8db0bf..5a8f1992f5cc677 100644
--- a/files/en-us/web/css/pseudo-elements/index.md
+++ b/files/en-us/web/css/pseudo-elements/index.md
@@ -91,6 +91,8 @@ These pseudo-elements are real elements that are not otherwise selectable.
   - : The button of an {{HTMLElement("input") }} of [`type="file"`](/en-US/docs/Web/HTML/Element/input/file).
 - {{CSSxRef("::part", "::part()")}}
   - : Any element within a [shadow tree](/en-US/docs/Web/API/Web_components/Using_shadow_DOM) that has a matching [`part`](/en-US/docs/Web/HTML/Global_attributes/part) attribute.
+- {{CSSxRef("::picker()")}}
+  - : The picker part of an element, for example the drop-down picker of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select).
 - {{CSSxRef("::slotted", "::slotted()")}}
   - : Any element placed into a slot inside an HTML template.
 
@@ -136,6 +138,7 @@ M
 P
 
 - {{CSSxRef("::part", "::part()")}}
+- {{CSSxRef("::picker()")}}
 - {{CSSxRef("::placeholder")}}
 
 S
diff --git a/files/en-us/web/html/element/selectedcontent/index.md b/files/en-us/web/html/element/selectedcontent/index.md
index 62373cffc0a6a64..06fc5f38dafb121 100644
--- a/files/en-us/web/html/element/selectedcontent/index.md
+++ b/files/en-us/web/html/element/selectedcontent/index.md
@@ -63,9 +63,7 @@ You can see a full example that includes the `<selectedcontent>` element in our
         >
       </th>
       <td>
-        <a href="/en-US/docs/Web/HTML/Content_categories#form-associated_"
-          >form-associated </a
-        >element.
+       None
       </td>
     </tr>
     <tr>

From edbc2b1756c84c152cca7e4f1c8b7c80a8faad8a Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Mon, 10 Mar 2025 11:06:36 +0000
Subject: [PATCH 08/15] Document appearance: base-select, tweak :open and
 :checked ref pages

---
 files/en-us/web/css/_colon_checked/index.md   |  4 +--
 files/en-us/web/css/_colon_open/index.md      |  2 +-
 .../web/css/_doublecolon_picker/index.md      |  2 +-
 files/en-us/web/css/appearance/index.md       | 27 +++++++++++++++++++
 4 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/files/en-us/web/css/_colon_checked/index.md b/files/en-us/web/css/_colon_checked/index.md
index 790613512822d40..148ebf31e734d92 100644
--- a/files/en-us/web/css/_colon_checked/index.md
+++ b/files/en-us/web/css/_colon_checked/index.md
@@ -7,7 +7,7 @@ browser-compat: css.selectors.checked
 
 {{CSSRef}}
 
-The **`:checked`** [CSS](/en-US/docs/Web/CSS) [pseudo-class](/en-US/docs/Web/CSS/Pseudo-classes) selector represents any **radio** ([`<input type="radio">`](/en-US/docs/Web/HTML/Element/input/radio)), **checkbox** ([`<input type="checkbox">`](/en-US/docs/Web/HTML/Element/input/checkbox)), or **option** ({{HTMLElement("option")}} in a {{HTMLElement("select")}}) element that is checked or toggled to an `on` state.
+The **`:checked`** [CSS](/en-US/docs/Web/CSS) [pseudo-class](/en-US/docs/Web/CSS/Pseudo-classes) selector represents any **radio** ([`<input type="radio">`](/en-US/docs/Web/HTML/Element/input/radio)), **checkbox** ([`<input type="checkbox">`](/en-US/docs/Web/HTML/Element/input/checkbox)), or **option** ({{HTMLElement("option")}} in a {{HTMLElement("select")}} element) that is checked or toggled to an `on` state.
 
 {{InteractiveExample("CSS Demo: :checked", "tabbed-shorter")}}
 
@@ -50,7 +50,7 @@ input:checked {
 The user can engage this state by checking/selecting an element, or disengage it by unchecking/deselecting the element.
 
 > [!NOTE]
-> Because browsers often treat `<option>`s as [replaced elements](/en-US/docs/Web/CSS/Replaced_element), the extent to which they can be styled with the `:checked` pseudo-class varies from browser to browser.
+> Because browsers often treat `<option>`s as [replaced elements](/en-US/docs/Web/CSS/Replaced_element), the extent to which they can be styled with the `:checked` pseudo-class varies from browser to browser. [Customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) functionality can be used to enable full customization of `<option>` elements just like any regular DOM element, in supporting browsers.
 
 ## Syntax
 
diff --git a/files/en-us/web/css/_colon_open/index.md b/files/en-us/web/css/_colon_open/index.md
index c585cf2b8e93429..4d2e00eec52d1cf 100644
--- a/files/en-us/web/css/_colon_open/index.md
+++ b/files/en-us/web/css/_colon_open/index.md
@@ -23,7 +23,7 @@ The `:open` pseudo-class selects any element currently in the open state, which
 
 - {{htmlelement("details")}} and {{htmlelement("dialog")}} elements that are in an open state, that is, they have the `open` attribute set.
 - {{htmlelement("input")}} elements that display a picker interface for the user to choose a value from (for example [`<input type="color">`](/en-US/docs/Web/HTML/Element/input/color)), when the picker is displayed.
-- {{htmlelement("select")}} elements that display a drop-down box for the user to choose a value from, when the drop-down is displayed.
+- {{htmlelement("select")}} elements that display a drop-down picker for the user to choose a value from, when the picker is displayed. Note that when implementing [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), the picker itself can be selected using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element.
 
 Note that the open and closed states are semantic states, and don't necessary correlate with the visibility of the element in question. For example, a `<details>` element that is expanded to show its content is open, and will be selected by the `details:open` selector, even if it is hidden with a {{cssxref("visibility")}} value of `hidden`.
 
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
index c9de8647a95a8fe..ea3b0720032d006 100644
--- a/files/en-us/web/css/_doublecolon_picker/index.md
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -36,7 +36,7 @@ This allows you to target all of the picker contents as a single entity, for exa
 
 ### Basic custom select usage
 
-To opt-in to custom select functionality, your `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
 
 ```css
 select,
diff --git a/files/en-us/web/css/appearance/index.md b/files/en-us/web/css/appearance/index.md
index bd584509f5aa1df..c8b415ec1656bbf 100644
--- a/files/en-us/web/css/appearance/index.md
+++ b/files/en-us/web/css/appearance/index.md
@@ -24,6 +24,7 @@ appearance: none;
 appearance: auto;
 appearance: menulist-button;
 appearance: textfield;
+appearance: base-select;
 
 /* Global values */
 appearance: inherit;
@@ -50,6 +51,13 @@ Some examples are provided, but the list is not exhaustive.
 
   - : Acts as `none` on elements with no special styling.
 
+- `base-select`
+
+  - : Opts the {{htmlelement("select")}} element and the {{cssxref("::picker()", "::picker(select)")}} pseudo-element into the browser-defined default (base) styles and behavior for [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select).
+
+    > [!NOTE]
+    > The specification currently defines the `base` value, which is intended to apply base browser styles more generally for UI elements they are available for. However, this does not appear to be supported in any browser.
+
 - `<compat-special>`
 
   - : One of `menulist-button` or `textfield`.
@@ -213,6 +221,25 @@ select.none {
 
 {{EmbedLiveSample("Apply_custom_styling", 1050, 100)}}
 
+### Basic custom select usage
+
+To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+
+```css
+select,
+::picker(select) {
+  appearance: base-select;
+}
+```
+
+You could then, for example, remove the picker's default black {{cssxref("border")}}:
+
+```css
+::picker(select) {
+  border: none;
+}
+```
+
 ## Specifications
 
 {{Specifications}}

From afdbacb8194656eb13d44807f65dc78893070ef1 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Mon, 10 Mar 2025 12:23:43 +0000
Subject: [PATCH 09/15] Document the ::picker-icon and ::checkmark pseudos

---
 .../forms/customizable_select/index.md        |  2 +-
 .../web/css/_doublecolon_checkmark/index.md   | 73 +++++++++++++++++
 .../web/css/_doublecolon_picker-icon/index.md | 78 +++++++++++++++++++
 .../web/css/_doublecolon_picker/index.md      |  4 +-
 files/en-us/web/css/pseudo-elements/index.md  | 23 ++++--
 5 files changed, 171 insertions(+), 9 deletions(-)
 create mode 100644 files/en-us/web/css/_doublecolon_checkmark/index.md
 create mode 100644 files/en-us/web/css/_doublecolon_picker-icon/index.md

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index ddf65e42bc926c0..d38fd603a305b4c 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -29,7 +29,7 @@ You can build customizable `<select>` elements using the following HTML and CSS
 - The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`.
 - The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
 - The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
-- The {{cssxref("::picker-icon")}} pseudo-element, which targets the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side.
+- The {{cssxref("::picker-icon")}} pseudo-element, which targets the picker icon inside the select `<button>` — the down-facing arrow on the inline-end side.
 - The {{cssxref(":checked")}} pseudo-class, which targets the currently-selected `<option>` element.
 - The {{cssxref("::checkmark")}} pseudo-element, which targets the checkmark placed inside the currently-selected `<option>` element to provide a visual indication of which one is selected.
 
diff --git a/files/en-us/web/css/_doublecolon_checkmark/index.md b/files/en-us/web/css/_doublecolon_checkmark/index.md
new file mode 100644
index 000000000000000..3dc2d857a7a34af
--- /dev/null
+++ b/files/en-us/web/css/_doublecolon_checkmark/index.md
@@ -0,0 +1,73 @@
+---
+title: ::checkmark
+slug: Web/CSS/::checkmark
+page-type: css-pseudo-element
+browser-compat: css.selectors.checkmark
+---
+
+{{CSSRef}}
+
+The **`::checkmark`** [CSS](/en-US/docs/Web/CSS) [pseudo-element](/en-US/docs/Web/CSS/Pseudo-elements) targets the checkmark placed inside the currently-selected {{htmlelement("option")}} element of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) to provide a visual indication of which one is selected.
+
+## Syntax
+
+```css-nolint
+::checkmark {
+  /* ... */
+}
+```
+
+### Parameters
+
+None.
+
+## Description
+
+The `::checkmark` pseudo-element targets the checkmark placed inside a [customizable select element's](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) currently-selected `<option>`.
+
+It is only available to target when the originating element has a picker and has base appearance set on it via the {{cssxref("appearance")}} property `base-select` value. Its generated box appears before any boxes generated by the {{cssxref("::before")}} pseudo-element, with the icon specified in default browser stylesheet; you can customize it using the {{cssxref("content")}} property.
+
+The `::checkmark` selector is useful for example if you want to hide the checkmark, use a custom icon, or adjust the checkmark's rendering position inside `<option>` elements.
+
+## Examples
+
+### Customizing the checkmark
+
+To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+
+```css
+select,
+::checkmark(select) {
+  appearance: base-select;
+}
+```
+
+Assuming [flexbox](/en-US/docs/Web/CSS/CSS_flexible_box_layout) is being used to lay out the `<option>` elements (which it is by default in customizable selects), you could then move the checkmark from the start of the row to the end by setting an {{cssxref("order")}} value on it greater than `0`, and aligning it to the end of the row using an `auto` {{cssxref("margin-left")}} value (see [Alignment and auto margins](/en-US/docs/Web/CSS/CSS_box_alignment/Box_alignment_in_flexbox#alignment_and_auto_margins)).
+
+The value of the {{cssxref("content")}} property could also be set to a different emoji, to set a different icon to display.
+
+```css
+option::checkmark {
+  order: 1;
+  margin-left: auto;
+  content: "☑️";
+}
+```
+
+See [Styling the current selection checkmark](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#styling_the_current_selection_checkmark) for a full example that uses this code, along with a live example rendering.
+
+## Specifications
+
+{{Specifications}}
+
+## Browser compatibility
+
+{{Compat}}
+
+## See also
+
+- {{htmlelement("select")}}, {{htmlelement("option")}}, {{htmlelement("optgroup")}}, {{htmlelement("label")}}, {{htmlelement("button")}}, {{htmlelement("selectedcontent")}}
+- {{cssxref("appearance")}}
+- {{cssxref("::picker()", "::picker(select)")}}, {{cssxref("::picker-icon")}}
+- {{cssxref(":open")}}, {{cssxref(":checked")}}
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/css/_doublecolon_picker-icon/index.md b/files/en-us/web/css/_doublecolon_picker-icon/index.md
new file mode 100644
index 000000000000000..01a1ef645abf0f2
--- /dev/null
+++ b/files/en-us/web/css/_doublecolon_picker-icon/index.md
@@ -0,0 +1,78 @@
+---
+title: ::picker-icon
+slug: Web/CSS/::picker-icon
+page-type: css-pseudo-element
+browser-compat: css.selectors.picker-icon
+---
+
+{{CSSRef}}
+
+The **`::picker-icon`** [CSS](/en-US/docs/Web/CSS) [pseudo-element](/en-US/docs/Web/CSS/Pseudo-elements) targets the picker icon inside form controls that have an icon associated with them. In the case of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), it selects the down-facing arrow on the inline-end side of the select {{htmlelement("button")}}.
+
+## Syntax
+
+```css-nolint
+::picker-icon {
+  /* ... */
+}
+```
+
+### Parameters
+
+None.
+
+## Description
+
+The `::picker-icon` pseudo-element targets the picker icon of form controls, that is, the icon shown on the control button. It is only available to target when the originating element has a picker and has base appearance set on it via the {{cssxref("appearance")}} property `base-select` value. Its generated box appears after any boxes generated by the {{cssxref("::after")}} pseudo-element, with the icon specified in default browser stylesheet; you can customize it using the {{cssxref("content")}} property.
+
+The `::picker-icon` selector can be used to select the down-facing arrow on the inline-end side of a [customizable select element's](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) button. This is useful for example if you want to customize the color or size of the icon, use a different icon, or animate it when the picker is opened and closed.
+
+Selecting customizable `<select>` picker icons is the only current use case for `::picker-icon`, but more may be added in the future.
+
+## Examples
+
+### Animating the picker icon
+
+To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+
+```css
+select,
+::picker-icon(select) {
+  appearance: base-select;
+}
+```
+
+You could then, for example, target the `::picker-icon` and give it a custom {{cssxref("color")}} and a {{cssxref("transition")}} so that changes to its {{cssxref("rotate")}} property are smoothly animated:
+
+```css
+select::picker-icon {
+  color: #999;
+  transition: 0.4s rotate;
+}
+```
+
+In the next rule, `::picker-icon` is combined with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the picker is open — to transition the icon to a `rotate` value of `180deg` when the `<select>` is opened.
+
+```css
+select:open::picker-icon {
+  rotate: 180deg;
+}
+```
+
+See [Styling the picker icon](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#styling_the_picker_icon) for a full example that uses this code, along with a live example rendering.
+
+## Specifications
+
+{{Specifications}}
+
+## Browser compatibility
+
+{{Compat}}
+
+## See also
+
+- {{htmlelement("select")}}, {{htmlelement("option")}}, {{htmlelement("optgroup")}}, {{htmlelement("label")}}, {{htmlelement("button")}}, {{htmlelement("selectedcontent")}}
+- {{cssxref("appearance")}}
+- {{cssxref("::picker()", "::picker(select)")}}, {{cssxref("::checkmark")}}
+- {{cssxref(":open")}}, {{cssxref(":checked")}}
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
index ea3b0720032d006..b02c1a25ec14a87 100644
--- a/files/en-us/web/css/_doublecolon_picker/index.md
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -26,7 +26,7 @@ The **`::picker()`** [CSS](/en-US/docs/Web/CSS) [pseudo-element](/en-US/docs/Web
 
 ## Description
 
-The `::picker()` pseudo-element targets the picker part of a form control, that is, the pop-up part that appears to allow you to make a selection when you press the control button.
+The `::picker()` pseudo-element targets the picker part of a form control, that is, the pop-up part that appears to allow you to make a selection when you press the control button. It is only available to target when the originating element has a picker and has base appearance set on it via the {{cssxref("appearance")}} property `base-select` value.
 
 The `::picker(select)` selector targets all descendants of customizable `<select>` element except for the first `<button>` child; these decendants are grouped together by the browser and rendered as the picker. The first `<button>` child represents the control button that opens the picker when pressed.
 
@@ -67,4 +67,4 @@ You could then, for example, remove the picker's default black {{cssxref("border
 - {{cssxref("appearance")}}
 - {{cssxref("::picker-icon")}}, {{cssxref("::checkmark")}}
 - {{cssxref(":open")}}, {{cssxref(":checked")}}
-- [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
+- [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select)
diff --git a/files/en-us/web/css/pseudo-elements/index.md b/files/en-us/web/css/pseudo-elements/index.md
index 5a8f1992f5cc677..ce15c9c7375a17b 100644
--- a/files/en-us/web/css/pseudo-elements/index.md
+++ b/files/en-us/web/css/pseudo-elements/index.md
@@ -76,8 +76,6 @@ These pseudo-elements behave like regular elements, fitting seamlessly within th
   - : Creates a pseudo-element that is the last child of the selected element.
 - {{CSSxRef("::marker")}}
   - : The automatically generated marker box of a list item.
-- {{CSSxRef("::placeholder")}}
-  - : The placeholder text in an input field.
 - {{CSSxRef("::backdrop")}}
   - : The backdrop of the originating element rendered in the [top layer](/en-US/docs/Glossary/Top_layer).
 
@@ -87,15 +85,26 @@ These pseudo-elements are real elements that are not otherwise selectable.
 
 - {{CSSxRef("::details-content")}}
   - : The expandable/collapsible contents of a {{HTMLElement("details")}} element.
-- {{CSSxRef("::file-selector-button")}}
-  - : The button of an {{HTMLElement("input") }} of [`type="file"`](/en-US/docs/Web/HTML/Element/input/file).
 - {{CSSxRef("::part", "::part()")}}
   - : Any element within a [shadow tree](/en-US/docs/Web/API/Web_components/Using_shadow_DOM) that has a matching [`part`](/en-US/docs/Web/HTML/Global_attributes/part) attribute.
-- {{CSSxRef("::picker()")}}
-  - : The picker part of an element, for example the drop-down picker of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select).
 - {{CSSxRef("::slotted", "::slotted()")}}
   - : Any element placed into a slot inside an HTML template.
 
+## Form-related pseudo-elements
+
+The pseudo-elements are related to form controls.
+
+- {{CSSxRef("::checkmark")}}
+  - : Targets the checkmark placed inside the currently-selected `<option>` element of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) to provide a visual indication of which one is selected.
+- {{CSSxRef("::file-selector-button")}}
+  - : The button of an {{HTMLElement("input") }} of [`type="file"`](/en-US/docs/Web/HTML/Element/input/file).
+- {{CSSxRef("::picker()")}}
+  - : The picker part of an element, for example the drop-down picker of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select).
+- {{CSSxRef("::picker-icon")}}
+  - : The picker icon inside form controls that have an icon associated with them. In the case of a [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), it selects the down-facing arrow on the inline-end side of the select {{htmlelement("button")}}.
+- {{CSSxRef("::placeholder")}}
+  - : The placeholder text in an input field.
+
 ## Alphabetical index
 
 Pseudo-elements defined by a set of CSS specifications include the following:
@@ -111,6 +120,7 @@ B
 
 C
 
+- {{CSSxRef("::checkmark")}}
 - {{CSSxRef("::cue")}} (and {{CSSxRef("::cue", "::cue()")}})
 
 D
@@ -139,6 +149,7 @@ P
 
 - {{CSSxRef("::part", "::part()")}}
 - {{CSSxRef("::picker()")}}
+- {{CSSxRef("::picker-icon")}}
 - {{CSSxRef("::placeholder")}}
 
 S

From 28e9f6e4778bba15ead57d638b5e9b4d06d37e75 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Mon, 10 Mar 2025 13:11:36 +0000
Subject: [PATCH 10/15] Add notes on implicit popover-invoker relationship and
 anchor reference

---
 files/en-us/web/api/popover_api/using/index.md         | 10 +++++++---
 files/en-us/web/css/_doublecolon_checkmark/index.md    |  2 +-
 files/en-us/web/css/_doublecolon_picker-icon/index.md  |  2 +-
 files/en-us/web/css/_doublecolon_picker/index.md       |  2 +-
 .../web/css/css_anchor_positioning/using/index.md      |  1 +
 5 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/files/en-us/web/api/popover_api/using/index.md b/files/en-us/web/api/popover_api/using/index.md
index 8b11b0e8c95e86a..fe7c1f94b295fb9 100644
--- a/files/en-us/web/api/popover_api/using/index.md
+++ b/files/en-us/web/api/popover_api/using/index.md
@@ -72,8 +72,12 @@ When a relationship is established between a popover and its control (invoker) v
 
 Setting up a relationship between a popover and its control in this manner also creates an implicit anchor reference between the two — see [Popover anchor positioning](#popover_anchor_positioning) for more details.
 
-> [!NOTE]
-> You can also set up a popover-invoker relationship using the `source` option of the {{domxref("HTMLElement.showPopover()")}} and {{domxref("HTMLElement.togglePopover()")}} methods, but bear in mind that in this case, only the focus navigation order changes are made, not the implicit ARIA relationship. This because the `source` option can be set to any kind of element, not just `<button>` elements, and it cannot be guaranteed that the relationship would make sense.
+## Other ways to set up a popover-invoker relationship
+
+You can set up a popover-invoker relationship in other ways, in addition to using the `popovertarget` attribute:
+
+- Using the `source` option of the {{domxref("HTMLElement.showPopover()")}} or {{domxref("HTMLElement.togglePopover()")}} methods. Bear in mind that in this case, only the focus navigation order changes are made, not the implicit ARIA relationship. This because the `source` option can be set to any kind of element, not just `<button>` elements, and it cannot be guaranteed that the relationship would make sense.
+- Between a {{htmlelement("select")}} element's dropdown picker and its select {{htmlelement("button")}}, when opting it into [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) functionality via the {{cssxref("appearance")}} property `base-select` value. In this case, an implicit popover-invoker relationship is created between the two.
 
 ## Using manual popover state
 
@@ -385,7 +389,7 @@ You can see an isolated example of this in our [Popover positioning example](htt
 
 There is another useful positioning option that the Popover API provides. If you want to position a popover relative to its invoker rather than the viewport or a positioned ancestor, you can take advantage of the fact that popovers and their invokers have an **implicit anchor reference**.
 
-Associating any kind of popover with its invoker using the [`popovertarget`](/en-US/docs/Web/HTML/Element/button#popovertarget) attribute or the `source` option of the {{domxref("HTMLElement.showPopover()")}} or {{domxref("HTMLElement.togglePopover()")}} methods creates an implicit anchor reference between the two. This causes the invoker to become the popover's **anchor element**, meaning that you can position the popover relative to it via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning).
+[Associating any kind of popover with its invoker](#other_ways_to_set_up_a_popover-invoker_relationship) creates an implicit anchor reference between the two. This causes the invoker to become the popover's **anchor element**, meaning that you can position the popover relative to it via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning).
 
 Because the association between the popover and the invoker is implicit, an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties. However, you still need to specify the positioning CSS.
 
diff --git a/files/en-us/web/css/_doublecolon_checkmark/index.md b/files/en-us/web/css/_doublecolon_checkmark/index.md
index 3dc2d857a7a34af..3d32148f3df6b1a 100644
--- a/files/en-us/web/css/_doublecolon_checkmark/index.md
+++ b/files/en-us/web/css/_doublecolon_checkmark/index.md
@@ -33,7 +33,7 @@ The `::checkmark` selector is useful for example if you want to hide the checkma
 
 ### Customizing the checkmark
 
-To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+To opt-in to customizable select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
 
 ```css
 select,
diff --git a/files/en-us/web/css/_doublecolon_picker-icon/index.md b/files/en-us/web/css/_doublecolon_picker-icon/index.md
index 01a1ef645abf0f2..c4f6a9d7ba84106 100644
--- a/files/en-us/web/css/_doublecolon_picker-icon/index.md
+++ b/files/en-us/web/css/_doublecolon_picker-icon/index.md
@@ -33,7 +33,7 @@ Selecting customizable `<select>` picker icons is the only current use case for
 
 ### Animating the picker icon
 
-To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+To opt-in to customizable select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
 
 ```css
 select,
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
index b02c1a25ec14a87..1d4b8bee56b1e77 100644
--- a/files/en-us/web/css/_doublecolon_picker/index.md
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -36,7 +36,7 @@ This allows you to target all of the picker contents as a single entity, for exa
 
 ### Basic custom select usage
 
-To opt-in to custom select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+To opt-in to customizable select functionality, the `<select>` element and its picker both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
 
 ```css
 select,
diff --git a/files/en-us/web/css/css_anchor_positioning/using/index.md b/files/en-us/web/css/css_anchor_positioning/using/index.md
index 9a79f9c5feb7f08..6fd63703792f25b 100644
--- a/files/en-us/web/css/css_anchor_positioning/using/index.md
+++ b/files/en-us/web/css/css_anchor_positioning/using/index.md
@@ -96,6 +96,7 @@ In some cases, an implicit anchor reference will be made between two elements, d
 
 - Declaratively associating a popover with a control using the [`popovertarget`](/en-US/docs/Web/HTML/Element/button#popovertarget) and [`id`](/en-US/docs/Web/HTML/Global_attributes/id) attributes.
 - Programmatically associating a popover action such as {{domxref("HTMLElement.showPopover", "showPopover()")}} with a control using the `source` option.
+- A {{htmlelement("select")}} element's dropdown picker and its select {{htmlelement("button")}} are opted into [customizable select element](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) functionality via the {{cssxref("appearance")}} property `base-select` value. In this case, an implicit popover-invoker relationship is created between the two, which also means they'll have an implicit anchor reference.
 
 > [!NOTE]
 > The methods above associate an anchor with an element, but they are not yet tethered. To tether them together, the positioned element needs to be positioned relative to its anchor, which is done with CSS.

From 86b1c9ab7e809623778dd2926d483f34417231ab Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Mon, 10 Mar 2025 17:14:26 +0000
Subject: [PATCH 11/15] Add default picker styling info, tweak other info

---
 .../forms/customizable_select/index.md        |  6 ++-
 .../api/htmlselectedcontentelement/index.md   |  2 +-
 .../web/css/_doublecolon_picker/index.md      | 37 +++++++++++++++++++
 .../web/html/element/selectedcontent/index.md |  2 +-
 4 files changed, 43 insertions(+), 4 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index d38fd603a305b4c..4fde1b9426f35fc 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -36,7 +36,7 @@ You can build customizable `<select>` elements using the following HTML and CSS
 In addition, the select `<button>` and the picker have the following behavior assigned to them automatically:
 
 - They have an invoker/popover relationship, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class. See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior.
-- They have an implicit anchor reference, meaning that the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning), and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+- They have an implicit anchor reference, meaning that the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). The browser default styles position the picker relative to the button (the anchor) and you can customize this position as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor). The browser default styles also define some position try fallbacks that reposition the picker if it is in danger of overflowing the viewport. Position try fallback are explained in [Handling overflow: try fallbacks and conditional hiding](/en-US/docs/Web/CSS/CSS_anchor_positioning/Try_options_hiding).
 
 > [!NOTE]
 > You can check browser support for customizable `<select>` by viewing the browser compatibility tables on the reference pages listed above.
@@ -345,7 +345,9 @@ These rules work together to make the `<select>` picker smoothly fade in and fad
 
 ## Positioning the picker using anchor positioning
 
-A customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically positioned relative to the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties, and you can customize the position of the picker as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
+A customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties.
+
+In addition, the [browser's default styles provide a default position](/en-US/docs/Web/CSS/::picker#picker_anchor_positioning), which you can customize as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
 
 In our demo, the position of the picker is set relative to its anchor by using the {{cssxref("anchor()")}} function inside its {{cssxref("top")}} and {{cssxref("left")}} property values:
 
diff --git a/files/en-us/web/api/htmlselectedcontentelement/index.md b/files/en-us/web/api/htmlselectedcontentelement/index.md
index 352dedd6ee383b3..f3e7dbde7586480 100644
--- a/files/en-us/web/api/htmlselectedcontentelement/index.md
+++ b/files/en-us/web/api/htmlselectedcontentelement/index.md
@@ -21,7 +21,7 @@ _This interface has no methods, but inherits methods from: {{DOMxRef("HTMLElemen
 
 ## Specifications
 
-{{Specifications}}
+Not currently part of a specification. See https://github.com/whatwg/html/pull/10633 for the relevant specification PR.
 
 ## Browser compatibility
 
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
index 1d4b8bee56b1e77..a815e6bf8e86764 100644
--- a/files/en-us/web/css/_doublecolon_picker/index.md
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -32,6 +32,43 @@ The `::picker(select)` selector targets all descendants of customizable `<select
 
 This allows you to target all of the picker contents as a single entity, for example if you want to customize its border, animate it when it appears and disappears, or position it somewhere different to the default position. Our [customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select) guide shows many examples of `::picker(select)` usage.
 
+### Picker popover behavior
+
+The select control `<button>` and the picker have an implicit invoker/popover relationship assigned to them automatically, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class.
+
+See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior, and see [Animating the picker drop-down using popover states](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#animating_the_picker_drop-down_using_popover_states) for a typical usae case allowed by the implicit popover association.
+
+### Picker anchor positioning
+
+A further side-effect of the implicit invoker/popover relationship mentioned above is that the button and the picker also have an implicit anchor reference, meaning that the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This has several advantages, most notably:
+
+- The browser default styles position the picker relative to the button (the anchor) and you can customize this position as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor). For reference, the related default styles are as follows:
+
+  ```css
+  inset: auto;
+  margin: 0;
+  min-inline-size: anchor-size(self-inline);
+  min-block-size: 1lh;
+  /* Go to the edge of the viewport, and add scrollbars if needed. */
+  max-block-size: stretch;
+  overflow: auto;
+  /* Below and span-right, by default. */
+  position-area: block-end span-inline-end;
+  ```
+
+- The browser default styles also define some position try fallbacks that reposition the picker if it is in danger of overflowing the viewport. Position try fallback are explained in [Handling overflow: try fallbacks and conditional hiding](/en-US/docs/Web/CSS/CSS_anchor_positioning/Try_options_hiding). For reference, the related default fallback styles are as follows:
+
+  ```css
+  position-try-order: most-block-size;
+  position-try-fallbacks:
+    /* First try above and span-right, */
+    /* then below but span-left, */
+    /* then above and span-left. */
+    block-start span-inline-end,
+    block-end span-inline-start,
+    block-start span-inline-start;
+  ```
+
 ## Examples
 
 ### Basic custom select usage
diff --git a/files/en-us/web/html/element/selectedcontent/index.md b/files/en-us/web/html/element/selectedcontent/index.md
index 06fc5f38dafb121..34d94f021d1d4f2 100644
--- a/files/en-us/web/html/element/selectedcontent/index.md
+++ b/files/en-us/web/html/element/selectedcontent/index.md
@@ -103,7 +103,7 @@ You can see a full example that includes the `<selectedcontent>` element in our
 
 ## Specifications
 
-{{Specifications}}
+Not currently part of a specification. See https://github.com/whatwg/html/pull/10633 for the relevant specification PR.
 
 ## Browser compatibility
 

From c0063ff71f737721540daa8d5b82c2b25b64d26c Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Sat, 15 Mar 2025 15:28:12 +0000
Subject: [PATCH 12/15] Fixes for josepharhar review comments

---
 .../extensions/forms/customizable_select/index.md         | 8 ++++----
 files/en-us/web/html/element/legend/index.md              | 4 +++-
 files/en-us/web/html/element/optgroup/index.md            | 4 +++-
 3 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 4fde1b9426f35fc..fbf15105642f255 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -63,10 +63,10 @@ Our example is a typical {{htmlelement("select")}} menu that allows you to choos
       <option value="dog">
         <span class="icon">🐶</span><span class="option-label">Dog</span>
       </option>
-      <option value="tortoise">
+      <option value="hamster">
         <span class="icon">🐹</span><span class="option-label">Hamster</span>
       </option>
-      <option value="parrot">
+      <option value="chicken">
         <span class="icon">🐔</span><span class="option-label">Chicken</span>
       </option>
       <option value="fish">
@@ -371,9 +371,9 @@ After the last two section, the final updated state of our `<select>` is rendere
 The above sections have covered all the new functionality available in customizable selects, and shown how it interacts with both classic single-line selects, and related modern features such as popovers and anchor positioning. There are some other `<select>` element features not mentioned above; this section talks about how they work alongside customizable selects:
 
 - [`<select multiple>`](/en-US/docs/Web/HTML/Attributes/multiple)
-  - : When the `multiple` attribute is set on customizable `<select>` elements, the styling works pretty much how you would expect — the styling applied to the `<option>` elements is presented as-is in the multiple select box, and the outer box itself is giving the same styling as the select `<button>` in the single select. Any styling related to the showing and hiding of the picker is ignored.
+  - : There isn't currently any official support specified for the `multiple` attribute on customizable `<select>` elements, however the styling works generally OK. The `<option>` elements are displayed as-is inside the multiple select box, and the outer box itself is given the same styling as the select `<button>` in the single select.
 - {{htmlelement("optgroup")}}
-  - : The default styling of `<optgroup>` elements is the same as in classic `<select>` elements — bolded and indented less than the contained options. You need to make sure to style the `<optgroup>` elements so they fit into the overall design, and bear in mind that they will behave just as containers are expected to behave in conventioal HTML.
+  - : The default styling of `<optgroup>` elements is the same as in classic `<select>` elements — bolded and indented less than the contained options. You need to make sure to style the `<optgroup>` elements so they fit into the overall design, and bear in mind that they will behave just as containers are expected to behave in conventional HTML. In customizable `<select>` elements, the {{htmlelement("legend")}} element is allowed as a child of `<optgroup>`, to provide a label that is easy to target and style. This replaces any text set in the `<optgroup>` element's `label` attribute, and it has the same semantics.
 
 ## See also
 
diff --git a/files/en-us/web/html/element/legend/index.md b/files/en-us/web/html/element/legend/index.md
index 1210f43bd298565..6919e01d05c5c63 100644
--- a/files/en-us/web/html/element/legend/index.md
+++ b/files/en-us/web/html/element/legend/index.md
@@ -9,6 +9,8 @@ browser-compat: html.elements.legend
 
 The **`<legend>`** [HTML](/en-US/docs/Web/HTML) element represents a caption for the content of its parent {{HTMLElement("fieldset")}}.
 
+In [customizable `<select>` elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), the {{htmlelement("legend")}} element is allowed as a child of `<optgroup>`, to provide a label that is easy to target and style. This replaces any text set in the `<optgroup>` element's `label` attribute, and it has the same semantics.
+
 {{InteractiveExample("HTML Demo: &lt;legend&gt;", "tabbed-standard")}}
 
 ```html interactive-example
@@ -77,7 +79,7 @@ See {{HTMLElement("form")}} for examples on `<legend>`.
       <th scope="row">Permitted parents</th>
       <td>
         A {{HTMLElement("fieldset")}} whose first child is this
-        <code>&#x3C;legend></code> element
+        <code>&#x3C;legend></code> element. In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>, a <code>&#x3C;legend></code> element is permitted as a child of {{htmlelement("optgroup")}} .
       </td>
     </tr>
     <tr>
diff --git a/files/en-us/web/html/element/optgroup/index.md b/files/en-us/web/html/element/optgroup/index.md
index de9a2d995bc4194..3f1fdc440675c42 100644
--- a/files/en-us/web/html/element/optgroup/index.md
+++ b/files/en-us/web/html/element/optgroup/index.md
@@ -9,6 +9,8 @@ browser-compat: html.elements.optgroup
 
 The **`<optgroup>`** [HTML](/en-US/docs/Web/HTML) element creates a grouping of options within a {{HTMLElement("select")}} element.
 
+In [customizable `<select>` elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), the {{htmlelement("legend")}} element is allowed as a child of `<optgroup>`, to provide a label that is easy to target and style. This replaces any text set in the `<optgroup>` element's `label` attribute, and it has the same semantics.
+
 {{InteractiveExample("HTML Demo: &lt;optgroup&gt;", "tabbed-standard")}}
 
 ```html interactive-example
@@ -83,7 +85,7 @@ This element includes the [global attributes](/en-US/docs/Web/HTML/Global_attrib
     </tr>
     <tr>
       <th scope="row">Permitted content</th>
-      <td>Zero or more {{HTMLElement("option")}} elements.</td>
+      <td>Zero or more {{HTMLElement("option")}} elements. In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>, a {{htmlelement("legend")}} element is permitted as a child of <code>&lt;optgroup&gt;</code>.</td>
     </tr>
     <tr>
       <th scope="row">Tag omission</th>

From 25bbe3d79e0029bf470dc07b2a74ccd738ddcd50 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Tue, 18 Mar 2025 13:48:56 +0000
Subject: [PATCH 13/15] Fixes for josepharhar review comments

---
 .../forms/customizable_select/index.md        | 21 +++++++++++--------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index fbf15105642f255..5b0b081a116108e 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -6,13 +6,13 @@ page-type: learn-module-chapter
 
 {{LearnSidebar}}
 
-This article explains how to use dedicated, modern HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements. This includes having full control over styling the select button, drop-down picker, arrow icon, checkbox to indicate which item is currently selected, each individual {{htmlelement("option")}} element, and more besides.
+This article explains how to use dedicated, modern HTML and CSS features together to create fully-customized {{htmlelement("select")}} elements. This includes having full control over styling the select button, drop-down picker, arrow icon, current selection checkmark, and each individual {{htmlelement("option")}} element.
 
 ## Background
 
 Traditionally it has been difficult to customize the look and feel of `<select>` elements because they contain internals that are styled at the operating system level, which can't be targeted using CSS. This includes the drop-down picker, arrow icon, etc.
 
-Previously, the best available option aside from using a custom JavaScript library was to set an {{cssxref("appearance")}} value of `none` on the `<select>` element to strip away some of the OS-level styling, and then use CSS to customize the bits that cna be styled. This technique is explained in [Advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
+Previously, the best available option aside from using a custom JavaScript library was to set an {{cssxref("appearance")}} value of `none` on the `<select>` element to strip away some of the OS-level styling, and then use CSS to customize the bits that can be styled. This technique is explained in [Advanced form styling](/en-US/docs/Learn_web_development/Extensions/Forms/Advanced_form_styling).
 
 Customizable `<select>` elements provide a solution to these issues. They allow you to build examples like the following, using only HTML and CSS:
 
@@ -24,9 +24,12 @@ You'll find out how to build this example in the sections below.
 
 You can build customizable `<select>` elements using the following HTML and CSS features:
 
-- Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be easily designed to fall back to classic selects in non-supporting browsers.
-- The {{htmlelement("selectedcontent")}} element, which contains a clone of the currently-selected `<option>` element's content (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This is the content visible inside the closed `<select>` element, otherwise known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
-- The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`.
+- Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. These work just the same as in "classic" selects, except that they have additional permitted content types. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be designed to fall back to "classic" selects in non-supporting browsers.
+- A {{htmlelement("button")}} element included as the first child inside the `<select>` element, which wasn't previously allowed in "classic" selects. When this is included, it replaces the default "button" rendering of the closed `<select>` element. You can then include arbitary content inside the `<button>`, to render whatever you want inside the closed `<select>`. This is comonly known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
+  > [!NOTE]
+  > The select `<button>` is {{glossary("inert")}} by default, to avoid any strange behavior caused by interactive children.
+- The {{htmlelement("selectedcontent")}} element, which can be included inside the `<select>` element's first child `<button>` element. This contains a clone of the currently-selected `<option>` element's content (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). In effect, this allows you to display the currently selected value inside the closed `<select>` element.
+- The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The browser puts all of the `<select>` element's content that isn't the first child `<button>` inside the picker.
 - The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
 - The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
 - The {{cssxref("::picker-icon")}} pseudo-element, which targets the picker icon inside the select `<button>` — the down-facing arrow on the inline-end side.
@@ -82,7 +85,7 @@ Our example is a typical {{htmlelement("select")}} menu that allows you to choos
 
 This is nearly the same as "classic" `<select>` markup, with the following differences:
 
-- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will place the selected option content inside the select button implicitly, but you won't be able to select it using CSS.
+- The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fall back to rendering the selected option's text inside the default button, and you won't be able to style it as easily.
 - The rest of the `<select>` contents represents the picker (the `<select>` drop-down menu). This obviously includes the `<option>` elements representing the different choices in the picker, but you can also include other content if desired.
 - Traditionally, `<option>` elements could only contain text, but in a customizable select you can include markup structures including images and more besides. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
 
@@ -137,7 +140,7 @@ select {
 }
 ```
 
-You can choose to opt-in one or the other, but in most cases you'll want to opt-in both.
+You can choose to opt-in just the `<select>` element to the new functionality, leaving the picker with the default OS styling, but in most cases, you'll want to opt-in both. You can't opt-in the picker without opting in the `<select>` element.
 
 Once this is done, the result is a very plain rendering of a `<select>` element:
 
@@ -228,7 +231,7 @@ option:not(option:last-of-type) {
 }
 ```
 
-Next a different `background` color is set on the odd-numbered `<options>` using {{cssxref(":nth-of-type()", ":nth-of-type(odd)")}} to implement zebra-striping, and a different `background` color is set on the `<options>` on focus and hover, to provide a useful visual highlight during selection:
+Next a different `background` color is set on the odd-numbered `<option>` elements using {{cssxref(":nth-of-type()", ":nth-of-type(odd)")}} to implement zebra-striping, and a different `background` color is set on the `<option>` elements on focus and hover, to provide a useful visual highlight during selection:
 
 ```css live-sample___third-render live-sample___fourth-render live-sample___full-render
 option:nth-of-type(odd) {
@@ -318,7 +321,7 @@ The list of transitioned properties features `opacity`, however it also includes
 - {{cssxref("display")}}
   - : The `display` values changes from `none` to `block` when the popover changes state from hidden to shown. This needs to be animated to ensure that other transitions are visible.
 - {{cssxref("overlay")}}
-  - : The `overlay` value changes from `none` to `auto` when the popover changes state from hidden to shown, to promote it to the {{glossary("top layer")}}, then back again when it is hidden to remove it. This needs to be animated to ensure the removal of the popover from the top layer is deferred until the transition completes, again ensuring the transition is visible.
+  - : The `overlay` value changes from `none` to `auto` when the popover changes state from hidden to shown, to promote it to the {{glossary("top layer")}}, then back again when it is hidden to remove it. This needs to be animated to ensure the removal of the popover from the top layer is deferred until the transition completes, ensuring the transition is visible.
 
 > [!NOTE]
 > The [`allow-discrete`](/en-US/docs/Web/CSS/transition-behavior#allow-discrete) value is needed to enable discrete property animations.

From 575f19e536bffc92fc6fdd9b36735c8b16e0c6c6 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Wed, 19 Mar 2025 13:01:13 +0000
Subject: [PATCH 14/15] Fixes for scottaohara review comments

---
 .../forms/advanced_form_styling/index.md      |  6 +-
 .../forms/customizable_select/index.md        | 68 +++++++++++--------
 .../web/css/_doublecolon_checkmark/index.md   |  3 +
 .../web/css/_doublecolon_picker/index.md      |  2 +-
 .../web/html/element/selectedcontent/index.md |  6 +-
 5 files changed, 53 insertions(+), 32 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md b/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
index 27259086fa5c60f..720345f70913171 100644
--- a/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/advanced_form_styling/index.md
@@ -369,11 +369,11 @@ Let's talk about some specifics of each of these types of control, highlighting
 
 ### Selects and datalists
 
-Selects and datalists are generally not too bad to style.
+Selects are generally not too bad to style. Many modern browsers now support [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), a set of HTML and CSS features that together enable full customization of `<select>` elements and their contents just like any regular DOM elements. In supporting browsers and codebases, you don't need to worry about these legacy techniques any more.
 
-Many modern browsers now support [Customizable select elements](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select), a set of HTML and CSS features that together enable full customization of `<select>` elements and their contents just like any regular DOM elements. In supporting browsers and codebases, you don't need to worry about these legacy techniques any more.
+Datalist styling is still limited.
 
-Even in non-supporting browsers and codebases, you can get a reasonable level of customization provided you don't want to vary the look and feel too much from the defaults. We've managed to get the basic look of the boxes looking pretty uniform and consistent. The datalist control is `<input type="text">` anyway, so we knew this wouldn't be a problem.
+For datalists, and for selects in browsers that don't support customizable selects, you can get an OK level of customization provided you don't want to vary the look and feel too much from the defaults. We've managed to get the basic look of the boxes looking pretty uniform and consistent. The `datalist` invoking control is an `<input type="text">` anyway, so we knew this wouldn't be a problem.
 
 Two things are slightly more problematic. First of all, the select's "arrow" icon that indicates it is a dropdown differs across browsers. It also tends to change if you increase the size of the select box, or resize in an ugly fashion. To fix this in our example we first used our old friend `appearance: none` to get rid of the icon altogether:
 
diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index 5b0b081a116108e..f312b7e997487a5 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -25,20 +25,20 @@ You'll find out how to build this example in the sections below.
 You can build customizable `<select>` elements using the following HTML and CSS features:
 
 - Plain old {{htmlelement("select")}}, {{htmlelement("option")}}, and {{htmlelement("optgroup")}} elements. These work just the same as in "classic" selects, except that they have additional permitted content types. The new features are built on top of existing select functionality as progressive enhancements, meaning that customizable selects can be designed to fall back to "classic" selects in non-supporting browsers.
-- A {{htmlelement("button")}} element included as the first child inside the `<select>` element, which wasn't previously allowed in "classic" selects. When this is included, it replaces the default "button" rendering of the closed `<select>` element. You can then include arbitary content inside the `<button>`, to render whatever you want inside the closed `<select>`. This is comonly known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down menu).
+- A {{htmlelement("button")}} element included as the first child inside the `<select>` element, which wasn't previously allowed in "classic" selects. When this is included, it replaces the default "button" rendering of the closed `<select>` element. This is comonly known as the **select {{htmlelement("button")}}** (as it is the button you need to press to open the drop-down picker).
   > [!NOTE]
-  > The select `<button>` is {{glossary("inert")}} by default, to avoid any strange behavior caused by interactive children.
+  > The select `<button>` is {{glossary("inert")}} by default so that if interactive children (for example, links or buttons) are included inside it, it will still be treated like a single button for interaction purposes.
 - The {{htmlelement("selectedcontent")}} element, which can be included inside the `<select>` element's first child `<button>` element. This contains a clone of the currently-selected `<option>` element's content (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). In effect, this allows you to display the currently selected value inside the closed `<select>` element.
-- The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the select drop-down menu, otherwise known as the **picker**. The browser puts all of the `<select>` element's content that isn't the first child `<button>` inside the picker.
+- The {{cssxref("::picker()", "::picker(select)")}} pseudo-element, which targets the entire contents of the picker. The browser puts all of the `<select>` element's content that isn't the first child `<button>` inside the picker.
 - The {{cssxref("appearance")}} property value `base-select`, which opts the `<select>` element and the `::picker(select)` pseudo-element into the browser-defined default styles and behavior for customizable select.
 - The {{cssxref(":open")}} pseudo-class, which targets the select `<button>` when the picker (`::picker(select)`) is open.
-- The {{cssxref("::picker-icon")}} pseudo-element, which targets the picker icon inside the select `<button>` — the down-facing arrow on the inline-end side.
+- The {{cssxref("::picker-icon")}} pseudo-element, which targets the icon inside the select `<button>` — the down-facing arrow on the inline-end side.
 - The {{cssxref(":checked")}} pseudo-class, which targets the currently-selected `<option>` element.
 - The {{cssxref("::checkmark")}} pseudo-element, which targets the checkmark placed inside the currently-selected `<option>` element to provide a visual indication of which one is selected.
 
-In addition, the select `<button>` and the picker have the following behavior assigned to them automatically:
+In addition, the select `<button>` and the drop-down picker have the following behavior assigned to them automatically:
 
-- They have an invoker/popover relationship, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class. See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior.
+- They have an invoker/popover relationship, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which provides the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class. See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior.
 - They have an implicit anchor reference, meaning that the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). The browser default styles position the picker relative to the button (the anchor) and you can customize this position as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor). The browser default styles also define some position try fallbacks that reposition the picker if it is in danger of overflowing the viewport. Position try fallback are explained in [Handling overflow: try fallbacks and conditional hiding](/en-US/docs/Web/CSS/CSS_anchor_positioning/Try_options_hiding).
 
 > [!NOTE]
@@ -61,42 +61,53 @@ Our example is a typical {{htmlelement("select")}} menu that allows you to choos
 
       <option value="">Please select a pet</option>
       <option value="cat">
-        <span class="icon">🐱</span><span class="option-label">Cat</span>
+        <span class="icon" aria-hidden="true">🐱</span
+        ><span class="option-label">Cat</span>
       </option>
       <option value="dog">
-        <span class="icon">🐶</span><span class="option-label">Dog</span>
+        <span class="icon" aria-hidden="true">🐶</span
+        ><span class="option-label">Dog</span>
       </option>
       <option value="hamster">
-        <span class="icon">🐹</span><span class="option-label">Hamster</span>
+        <span class="icon" aria-hidden="true">🐹</span
+        ><span class="option-label">Hamster</span>
       </option>
       <option value="chicken">
-        <span class="icon">🐔</span><span class="option-label">Chicken</span>
+        <span class="icon" aria-hidden="true">🐔</span
+        ><span class="option-label">Chicken</span>
       </option>
       <option value="fish">
-        <span class="icon">🐟</span><span class="option-label">Fish</span>
+        <span class="icon" aria-hidden="true">🐟</span
+        ><span class="option-label">Fish</span>
       </option>
       <option value="snake">
-        <span class="icon">🐍</span><span class="option-label">Snake</span>
+        <span class="icon" aria-hidden="true">🐍</span
+        ><span class="option-label">Snake</span>
       </option>
     </select>
   </p>
 </form>
 ```
 
-This is nearly the same as "classic" `<select>` markup, with the following differences:
+> [!NOTE]
+> The [`aria-hidden="true"`](/en-US/docs/Web/Accessibility/ARIA/Reference/Attributes/aria-hidden) attribute is included on the icons so that they will be hidden from assistive technologies, avoiding the option values being annouced twice (for example, "cat cat").
+
+The example markup is nearly the same as "classic" `<select>` markup, with the following differences:
 
 - The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fall back to rendering the selected option's text inside the default button, and you won't be able to style it as easily.
-- The rest of the `<select>` contents represents the picker (the `<select>` drop-down menu). This obviously includes the `<option>` elements representing the different choices in the picker, but you can also include other content if desired.
-- Traditionally, `<option>` elements could only contain text, but in a customizable select you can include markup structures including images and more besides. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
+  > [!NOTE]
+  > You _can_ include arbitrary content inside the `<button>` to render whatever you want inside the closed `<select>`, but be careful when doing this. What you render can alter the `<select>` element's accessible value exposed to assistive technology.
+- The rest of the `<select>` contents represents the drop-down picker, which is usually limited to the `<option>` elements representing the different choices in the picker. You could include other arbitrary content in the picker, but it is not recommended.
+- Traditionally, `<option>` elements could only contain text, but in a customizable select you can include other markup structures like images, other non-interactive text-level semantic elements, and more. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
 
   > [!NOTE]
   > Because the `<option>` content can contain multi-level DOM sub-trees, not just text nodes, there are rules concerning how the browser should extract the [current `<select>` value](/en-US/docs/Web/API/HTMLSelectElement/value) via JavaScript. The selected `<option>` element's {{domxref("Node.textContent", "textContent")}} property value is retrieved, {{jsxref("String.prototype.trim", "trim()")}} is run on it, and the result is set as the `<select>` value.
 
-This design allows non-supporting browsers to fall back to a classic `<select>` menu. The `<button><selectedcontent></selectedcontent></button>` structure will be ignored completely, and the non-text `<option>` contents will be stripped out to just leave the text node contents, but the result will still function.
+This design allows non-supporting browsers to fall back to a classic `<select>` experience. The `<button><selectedcontent></selectedcontent></button>` structure will be ignored completely, and the non-text `<option>` contents will be stripped out to just leave the text node contents, but the result will still function.
 
 ## Opting in to the custom select rendering
 
-To opt-in to the custom select functionality, your `<select>` element and its picker (represented by the `::picker(select)` pseudo-element) both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
+To opt-in to the custom select functionality, your `<select>` element and its drop-down picker (represented by the `::picker(select)` pseudo-element) both need to have an {{cssxref("appearance")}} value of `base-select` set on them:
 
 ```css live-sample___plain-render live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select,
@@ -164,7 +175,7 @@ select:focus {
 
 ## Styling the picker icon
 
-To style the picker icon inside the select `<button>` — the little down-facing arrow on the inline-end side — you can target it with the {{cssxref("::picker-icon")}} pseudo-element. In the following code gives the icon a custom {{cssxref("color")}} and a `transition` so that changes to its {{cssxref("rotate")}} property are smoothly animated:
+To style the icon inside the select `<button>` — the little down-facing arrow on the inline-end side — you can target it with the {{cssxref("::picker-icon")}} pseudo-element. In the following code gives the icon a custom {{cssxref("color")}} and a `transition` so that changes to its {{cssxref("rotate")}} property are smoothly animated:
 
 ```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select::picker-icon {
@@ -173,7 +184,7 @@ select::picker-icon {
 }
 ```
 
-Next up, `::picker-icon` is combined with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the picker is open — to give the icon a `rotate` value of `180deg` when the `<select>` is opened.
+Next up, `::picker-icon` is combined with the {{cssxref(":open")}} pseudo-class — which targets the select `<button>` only when the drop-down picker is open — to give the icon a `rotate` value of `180deg` when the `<select>` is opened.
 
 ```css live-sample___second-render live-sample___third-render live-sample___fourth-render live-sample___full-render
 select:open::picker-icon {
@@ -185,9 +196,9 @@ Let's have a look at the work so far — note how the picker arrow rotates smoot
 
 {{EmbedLiveSample("second-render", "100%", "200px")}}
 
-## Styling the picker drop-down menu
+## Styling the drop-down picker
 
-The select picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As mentioned earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
+The drop-down picker can be targeted using the {{cssxref("::picker()", "::picker(select)")}} pseudo-element. As mentioned earlier, the picker contains everything inside the `<select>` element that isn't the button and the `<selectedcontent>`. In our example, this means all the `<option>` elements and ther contents.
 
 First of all, the picker's default black {{cssxref("border")}} is removed:
 
@@ -269,11 +280,11 @@ selectedcontent .icon {
 }
 ```
 
-This does not affect the styling of the `<option>` contents as they appear inside the picker.
+This does not affect the styling of the `<option>` contents as they appear inside the drop-down picker.
 
 ## Styling the currently selected option
 
-To style the currently selected `<option>` as it appears inside the picker, you can target it using the {{cssxref(":checked")}} pseudo-class. This is used to set the selected `<option>` element's {{cssxref("font-weight")}} to `bold`:
+To style the currently selected `<option>` as it appears inside the drop-down picker, you can target it using the {{cssxref(":checked")}} pseudo-class. This is used to set the selected `<option>` element's {{cssxref("font-weight")}} to `bold`:
 
 ```css live-sample___fourth-render live-sample___full-render
 option:checked {
@@ -297,13 +308,16 @@ option::checkmark {
 }
 ```
 
+> [!NOTE]
+> When changing the icon like this, you should make sure to change it to something that will be announced as a checkmark (or similar) by assistive technologies so it makes sense to their users.
+
 Let's check in again on how the example is rendering. The updated state after the last three sections is as follows:
 
 {{EmbedLiveSample("fourth-render", "100%", "200px")}}
 
-## Animating the picker drop-down using popover states
+## Animating the picker using popover states
 
-The customizable `<select>` element's select `button` and picker are automatically given an invoker/popover relationship, as described in [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using). There are many advantages that this brings to `<select>` elements; our example takes advantage of the ability to animate between popover hidden and showing states using transitions. The {{cssxref(":popover-open")}} pseudo-class represents popovers in the showing state.
+The customizable `<select>` element's select `button` and drop-down picker are automatically given an invoker/popover relationship, as described in [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using). There are many advantages that this brings to `<select>` elements; our example takes advantage of the ability to animate between popover hidden and showing states using transitions. The {{cssxref(":popover-open")}} pseudo-class represents popovers in the showing state.
 
 The technique is covered quickly in this section — read [Animating popovers](/en-US/docs/Web/API/Popover_API/Using#animating_popovers) for a more detailed description.
 
@@ -344,11 +358,11 @@ Finally, because the picker is being transitioned while it is moving from `displ
 }
 ```
 
-These rules work together to make the `<select>` picker smoothly fade in and fade out when the `<select>` is opeed and closed.
+These rules work together to make the picker smoothly fade in and fade out when the `<select>` is opened and closed.
 
 ## Positioning the picker using anchor positioning
 
-A customizable `<select>` element's select `<button>` and picker have have an implicit anchor reference, and the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties.
+A customizable `<select>` element's select `<button>` and drop-down picker have have an implicit anchor reference, and the picker is automatically associated with the select `<button>` via [CSS anchor positioning](/en-US/docs/Web/CSS/CSS_anchor_positioning). This means that an explicit association does not need to be made using the {{cssxref("anchor-name")}} and {{cssxref("position-anchor")}} properties.
 
 In addition, the [browser's default styles provide a default position](/en-US/docs/Web/CSS/::picker#picker_anchor_positioning), which you can customize as explained in [Positioning elements relative to their anchor](/en-US/docs/Web/CSS/CSS_anchor_positioning/Using#positioning_elements_relative_to_their_anchor).
 
diff --git a/files/en-us/web/css/_doublecolon_checkmark/index.md b/files/en-us/web/css/_doublecolon_checkmark/index.md
index 3d32148f3df6b1a..0ac7395dc346e56 100644
--- a/files/en-us/web/css/_doublecolon_checkmark/index.md
+++ b/files/en-us/web/css/_doublecolon_checkmark/index.md
@@ -54,6 +54,9 @@ option::checkmark {
 }
 ```
 
+> [!NOTE]
+> When changing the icon like this, you should make sure to change it to something that will be announced as a checkmark (or similar) by assistive technologies so it makes sense to their users.
+
 See [Styling the current selection checkmark](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#styling_the_current_selection_checkmark) for a full example that uses this code, along with a live example rendering.
 
 ## Specifications
diff --git a/files/en-us/web/css/_doublecolon_picker/index.md b/files/en-us/web/css/_doublecolon_picker/index.md
index a815e6bf8e86764..0487fab36d36a24 100644
--- a/files/en-us/web/css/_doublecolon_picker/index.md
+++ b/files/en-us/web/css/_doublecolon_picker/index.md
@@ -36,7 +36,7 @@ This allows you to target all of the picker contents as a single entity, for exa
 
 The select control `<button>` and the picker have an implicit invoker/popover relationship assigned to them automatically, as specified by the [Popover API](/en-US/docs/Web/API/Popover_API), which brings several advantages such as accessibility semantics, tabbing order adjustments, and the ability to select the picker when open via the {{cssxref(":popover-open")}} pseudo-class.
 
-See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior, and see [Animating the picker drop-down using popover states](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#animating_the_picker_drop-down_using_popover_states) for a typical usae case allowed by the implicit popover association.
+See [Using the Popover API](/en-US/docs/Web/API/Popover_API/Using) for more details of popover behavior, and see [Animating the picker drop-down using popover states](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#animating_the_picker_using_popover_states) for a typical usae case allowed by the implicit popover association.
 
 ### Picker anchor positioning
 
diff --git a/files/en-us/web/html/element/selectedcontent/index.md b/files/en-us/web/html/element/selectedcontent/index.md
index 34d94f021d1d4f2..3edf1d3fb3e7301 100644
--- a/files/en-us/web/html/element/selectedcontent/index.md
+++ b/files/en-us/web/html/element/selectedcontent/index.md
@@ -11,7 +11,11 @@ The **`<selectedcontent>`** [HTML](/en-US/docs/Web/HTML) element contains a clon
 
 ## Attributes
 
-This element includes the [global attributes](/en-US/docs/Web/HTML/Global_attributes), but has no other attributes defined on it.
+The `<selectedcontent>` element includes the [global attributes](/en-US/docs/Web/HTML/Global_attributes), but they will essentially be ignored because when used correctly as a child of a select `<button>`, the element is rendered {{glossary("inert")}}.
+
+The select `<button>` and all its content are inert by default so that if interactive children (for example, links or buttons) are included inside it, it will still be treated like a single button for interaction purposes.
+
+No other attributes are defined on `<selectedcontent>`.
 
 ## Description
 

From 97b6e43c819e7e930039254bcd200468b3ea3d57 Mon Sep 17 00:00:00 2001
From: Chris Mills <chrisdavidmills@gmail.com>
Date: Thu, 20 Mar 2025 08:47:33 +0000
Subject: [PATCH 15/15] Accessibility and <select> content fixes

---
 .../extensions/forms/customizable_select/index.md      | 10 +++++-----
 files/en-us/web/css/_doublecolon_checkmark/index.md    |  4 ++--
 files/en-us/web/html/element/select/index.md           |  5 ++++-
 3 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
index f312b7e997487a5..47e9e277d429d6c 100644
--- a/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
+++ b/files/en-us/learn_web_development/extensions/forms/customizable_select/index.md
@@ -97,7 +97,7 @@ The example markup is nearly the same as "classic" `<select>` markup, with the f
 - The `<button><selectedcontent></selectedcontent></button>` structure represents the select {{htmlelement("button")}}; the {{htmlelement("selectedcontent")}} element contains a clone of the currently-selected {{htmlelement("option")}} (created using {{domxref("Node.cloneNode", "cloneNode()")}} under the hood). This allows you to select and [adjust the styling of the selected `<option>` contents as shown inside the select button](#adjusting_the_styling_of_the_selected_option_contents_inside_the_select_button). If this structure is not included in your markup, the browser will fall back to rendering the selected option's text inside the default button, and you won't be able to style it as easily.
   > [!NOTE]
   > You _can_ include arbitrary content inside the `<button>` to render whatever you want inside the closed `<select>`, but be careful when doing this. What you render can alter the `<select>` element's accessible value exposed to assistive technology.
-- The rest of the `<select>` contents represents the drop-down picker, which is usually limited to the `<option>` elements representing the different choices in the picker. You could include other arbitrary content in the picker, but it is not recommended.
+- The rest of the `<select>` contents represents the drop-down picker, which is usually limited to the `<option>` elements representing the different choices in the picker. You can include other content in the picker, but it is not recommended.
 - Traditionally, `<option>` elements could only contain text, but in a customizable select you can include other markup structures like images, other non-interactive text-level semantic elements, and more. In our example, each `<option>` contains two {{htmlelement("span")}} elements containing an icon and a text label respectively, allowing each one to be styled and positioned independently.
 
   > [!NOTE]
@@ -304,12 +304,12 @@ Finally, the value of the {{cssxref("content")}} property is set to a different
 option::checkmark {
   order: 1;
   margin-left: auto;
-  content: "☑️";
+  content: "☑️" / "";
 }
 ```
 
 > [!NOTE]
-> When changing the icon like this, you should make sure to change it to something that will be announced as a checkmark (or similar) by assistive technologies so it makes sense to their users.
+> When changing the icon like this, you should mark it as decorative by including an empty alt text string after the slash in the `content` property value, as shown above. This causes assistive technology (AT) to not announce anything for it, so it will make more sense to users of those tools. In general, AT and the underlying platform will handle announcing whether an option is selected or not, so you don't need to do it a second time.
 
 Let's check in again on how the example is rendering. The updated state after the last three sections is as follows:
 
@@ -385,10 +385,10 @@ After the last two section, the final updated state of our `<select>` is rendere
 
 ## Customizing other classic select features
 
-The above sections have covered all the new functionality available in customizable selects, and shown how it interacts with both classic single-line selects, and related modern features such as popovers and anchor positioning. There are some other `<select>` element features not mentioned above; this section talks about how they work alongside customizable selects:
+The above sections have covered all the new functionality available in customizable selects, and shown how it interacts with both classic single-line selects, and related modern features such as popovers and anchor positioning. There are some other `<select>` element features not mentioned above; this section talks about how they currently work alongside customizable selects:
 
 - [`<select multiple>`](/en-US/docs/Web/HTML/Attributes/multiple)
-  - : There isn't currently any official support specified for the `multiple` attribute on customizable `<select>` elements, however the styling works generally OK. The `<option>` elements are displayed as-is inside the multiple select box, and the outer box itself is given the same styling as the select `<button>` in the single select.
+  - : There isn't currently any support specified for the `multiple` attribute on customizable `<select>` elements, but this will be worked on in the future.
 - {{htmlelement("optgroup")}}
   - : The default styling of `<optgroup>` elements is the same as in classic `<select>` elements — bolded and indented less than the contained options. You need to make sure to style the `<optgroup>` elements so they fit into the overall design, and bear in mind that they will behave just as containers are expected to behave in conventional HTML. In customizable `<select>` elements, the {{htmlelement("legend")}} element is allowed as a child of `<optgroup>`, to provide a label that is easy to target and style. This replaces any text set in the `<optgroup>` element's `label` attribute, and it has the same semantics.
 
diff --git a/files/en-us/web/css/_doublecolon_checkmark/index.md b/files/en-us/web/css/_doublecolon_checkmark/index.md
index 0ac7395dc346e56..5979705637af8aa 100644
--- a/files/en-us/web/css/_doublecolon_checkmark/index.md
+++ b/files/en-us/web/css/_doublecolon_checkmark/index.md
@@ -50,12 +50,12 @@ The value of the {{cssxref("content")}} property could also be set to a differen
 option::checkmark {
   order: 1;
   margin-left: auto;
-  content: "☑️";
+  content: "☑️" / "";
 }
 ```
 
 > [!NOTE]
-> When changing the icon like this, you should make sure to change it to something that will be announced as a checkmark (or similar) by assistive technologies so it makes sense to their users.
+> When changing the icon like this, you should mark it as decorative by including an empty alt text string after the slash in the `content` property value, as shown above. This causes assistive technology (AT) to not announce anything for it, so it will make more sense to users of those tools. In general, AT and the underlying platform will handle announcing whether an option is selected or not, so you don't need to do it a second time.
 
 See [Styling the current selection checkmark](/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select#styling_the_current_selection_checkmark) for a full example that uses this code, along with a live example rendering.
 
diff --git a/files/en-us/web/html/element/select/index.md b/files/en-us/web/html/element/select/index.md
index d0b87699a180e2d..5b93a47c69e7c61 100644
--- a/files/en-us/web/html/element/select/index.md
+++ b/files/en-us/web/html/element/select/index.md
@@ -262,7 +262,10 @@ You'll see that:
       <th scope="row">Permitted content</th>
       <td>
         Zero or more {{HTMLElement("option")}},
-        {{HTMLElement("optgroup")}}, or {{HTMLElement("hr")}} elements in traditional <code>&lt;select&gt;</code> elements. In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>, the select {{htmlelement("button")}} is optionally included as a child <code>&lt;button&gt;</code> element with a nested {{htmlelement("selectedcontent")}} element, and the picker is defined as any other arbitrary content including zero or more <code>&lt;option&gt;</code>, <code>&lt;optgroup&gt;</code>, or <code>&lt;hr&gt;</code> elements.
+        {{HTMLElement("optgroup")}}, or {{HTMLElement("hr")}} elements in traditional <code>&lt;select&gt;</code> elements. In <a href="/en-US/docs/Learn_web_development/Extensions/Forms/Customizable_select">customizable select elements</a>:
+        <ul>
+        <li>The select {{htmlelement("button")}} is optionally included as a child <code>&lt;button&gt;</code> element with a nested {{htmlelement("selectedcontent")}} element.</li>
+        <li>The drop-down picker is defined as any other content, which can include zero or more <code>&lt;option&gt;</code>, <code>&lt;optgroup&gt;</code>, <code>&lt;hr&gt;</code>, {{htmlelement("div")}}, {{htmlelement("script")}}, {{htmlelement("template")}}, and {{htmlelement("noscript")}} elements.
       </td>
     </tr>
     <tr>