Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Define base appearance for <select> #10629

Open
wants to merge 25 commits into
base: main
Choose a base branch
from
Open
Changes from 22 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8e17138
Define base appearance for <select>
josepharhar Jul 18, 2024
f8cd659
rewrote a lot
josepharhar Nov 11, 2024
9c41826
Merge branch 'main' into selectrendering
josepharhar Nov 11, 2024
85b785f
prevent select button from being default submit button
josepharhar Nov 13, 2024
5e5dcb3
Merge branch 'main' into selectrendering
josepharhar Dec 5, 2024
8dc3b0e
reverse tree order
josepharhar Dec 5, 2024
46f457e
code around elements
josepharhar Dec 5, 2024
d9bc0b4
nits
josepharhar Dec 5, 2024
72c006b
add open the picker paragraph
josepharhar Dec 5, 2024
2400840
add arrow key events
josepharhar Dec 5, 2024
dcf650b
replace activation behavior for options
josepharhar Dec 6, 2024
9758b7b
Update focus another option
josepharhar Dec 13, 2024
3c8e35d
add pageup/pagedown
josepharhar Dec 26, 2024
c151264
move more of option picking into algorithm
josepharhar Jan 16, 2025
7a18a77
move more user interaction stuff into algorithms
josepharhar Jan 16, 2025
45bbc64
add separate opt in for picker
josepharhar Jan 23, 2025
c5b6645
dom feedback
josepharhar Jan 23, 2025
9694785
Merge branch 'main' into selectrendering
josepharhar Feb 13, 2025
2ad7144
add aria practices link for keyboard behavior
josepharhar Feb 13, 2025
b4cfd59
fix rfc error
josepharhar Feb 13, 2025
5282a71
Add check for primary mouse button
josepharhar Feb 20, 2025
c04849e
Fix typo in attribute
josepharhar Feb 24, 2025
bb763db
update pseudo-elements for native/primitive appearance
josepharhar Mar 13, 2025
8d55bcb
fix typo
josepharhar Mar 13, 2025
4acf5f6
add more base appearance
josepharhar Mar 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 161 additions & 14 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -3359,6 +3359,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<ul class="brief">
<li>The <dfn data-x-href="https://w3c.github.io/uievents/#mouseevent"><code>MouseEvent</code></dfn> interface</li>
<li>The <code>MouseEvent</code> interface's <dfn data-x="dom-MouseEvent-relatedTarget" data-x-href="https://w3c.github.io/uievents/#dom-mouseevent-relatedtarget"><code>relatedTarget</code></dfn> attribute</li>
<li>The <code>MouseEvent</code> interface's <dfn data-x="dom-MouseEvent-button" data-x-href="https://w3c.github.io/uievents/#dom-mouseevent-button"><code>button</code></dfn> attribute</li>
<li><dfn data-x-href="https://w3c.github.io/uievents/#dictdef-mouseeventinit"><code>MouseEventInit</code></dfn> dictionary type</li>

<li>The <dfn data-x-href="https://w3c.github.io/uievents/#focusevent"><code>FocusEvent</code></dfn> interface</li>
Expand Down Expand Up @@ -3859,6 +3860,14 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The <dfn data-x-href="https://drafts.csswg.org/css-fonts/#valdef-font-stretch-ultra-expanded">'ultra-expanded'</dfn> value</li>
</ul>

<p>The following features are defined in <cite>CSS Forms</cite>:
<ref>CSSFORMS</ref></p>

<ul class="brief">
<li>The <dfn data-x-href="https://drafts.csswg.org/css-forms/#picker-pseudo-element">picker
pseudo-element</dfn></li>
</ul>

<p>The following features are defined in <cite>CSS Grid Layout</cite>: <ref>CSSGRID</ref></p>

<ul class="brief">
Expand Down Expand Up @@ -3997,6 +4006,7 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<li>The concept <dfn data-x-href="https://drafts.csswg.org/css-ui/#widget">widget</dfn></li>
<li>The concept <dfn data-x-href="https://drafts.csswg.org/css-ui/#native-appearance">native appearance</dfn></li>
<li>The concept <dfn data-x-href="https://drafts.csswg.org/css-ui/#primitive-appearance">primitive appearance</dfn></li>
<li>The concept <dfn data-x-href="https://drafts.csswg.org/css-ui/#base-appearance">base appearance</dfn></li>
<li>The concept <dfn data-x-href="https://drafts.csswg.org/css-ui/#element-with-default-preferred-size">element with default preferred size</dfn></li>
<li>The <dfn data-x-href="https://drafts.csswg.org/css-ui/#non-devolvable">non-devolvable widget</dfn> and
<dfn data-x-href="https://drafts.csswg.org/css-ui/#devolvable">devolvable widget</dfn> classification, and the related
Expand Down Expand Up @@ -53764,18 +53774,43 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> {

<div w-nodev>

<p>If the <code data-x="attr-select-multiple">multiple</code> attribute is absent, and the element
is not <span data-x="concept-fe-disabled">disabled</span>, then the user agent should allow the
user to pick an <code>option</code> element in its <span data-x="concept-select-option-list">list
of options</span> that is itself not <span data-x="concept-option-disabled">disabled</span>. Upon
this <code>option</code> element being <dfn data-x="concept-select-pick">picked</dfn> (either
through a click, or through unfocusing the element after changing its value, or through a <span
data-x="option-command">menu command</span>, or through any other mechanism), and before the
relevant user interaction event <!-- interaction event spec point --> is queued (e.g. before the
<code data-x="event-click">click</code> event), the user agent must set the <span
data-x="concept-option-selectedness">selectedness</span> of the picked <code>option</code> element
to true, set its <span data-x="concept-option-dirtiness">dirtiness</span> to true, and then
<span>send <code>select</code> update notifications</span>.</p>
<p>The user agent should allow the user to <dfn data-x="concept-select-pick">pick</dfn> an
<code>option</code> element from a <code>select</code> element in its <span
data-x="concept-select-option-list">list of options</span> (either through a click, or through
unfocusing the element after changing its value, or through a <span data-x="option-command">menu
command</span>, or through any other mechanism) by running the <span>pick an option</span>
algorithm given the <code>select</code> element, the <code>option</code> element, and if
<code>select</code> and its <span>select popover </span> are both being rendered with <span>base
appearance</span>, a corresponding <code data-x="event-keydown">keydown</code> or <code
data-x="event-mouseup">mouseup</code> event, otherwise null.</p>

<p>To <dfn>pick an option</dfn> given a <code>select</code> element <var>select</var>, an
<code>option</code> element <var>option</var>, and an <code>Event</code> or null
<var>event</var>:</p>

<ol>
<li><p>If <var>select</var> has the <code data-x="attr-select-multiple">multiple</code> attribute
or <var>select</var> is <span data-x="concept-fe-disabled">disabled</span>, then return.</p></li>

<li><p>If <var>event</var> is not null and <var>event</var>'s <span>canceled flag</span> is set,
then return.</p></li>

<li><p>If <var>event</var> is a <code>MouseEvent</code> and <var>event</var>'s <code
data-x="dom-MouseEvent-button">button</code> attribute is not 1, then return.</p></li>

<li><p>Set <var>option</var>'s <span data-x="concept-option-selectedness">selectedness</span> to
true.</p></li>

<li><p>Set <var>option</var>'s <span data-x="concept-option-dirtiness">dirtiness</span> to
true.</p></li>

<li><p><span>Send <code>select</code> update notifications</span> given
<var>select</var>.</p></li>

<li><p>If <var>select</var> is being rendered as a <span>drop-down box</span> with <span>base
appearance</span>, then run the <span>hide popover algorithm</span> given <var>select</var>'s
<span>select popover</span>.</p></li>
</ol>

<p>If the <code data-x="attr-select-multiple">multiple</code> attribute is absent, whenever an
<code>option</code> element in the <code>select</code> element's <span
Expand Down Expand Up @@ -53855,6 +53890,42 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> {
options</span> <dfn data-x="ask for a reset">asks for a reset</dfn>, then run that
<code>select</code> element's <span>selectedness setting algorithm</span>.</p>

<p>If the <code>select</code> is being rendered as a <span>drop-down box</span> with <span>base
appearance</span>, then the user agent should allow the user to <dfn
data-x="select-open-picker">open the picker</dfn> given a corresponding <code>select</code>
element <var>select</var> and a corresponding <code data-x="event-mousedown">mousedown</code> or
<code data-x="event-keydown">keydown</code> event <var>event</var>:

<ol>
<li><p>If <var>event</var>'s <span>canceled flag</span> is set, then return.</p></li>

<li><p>If <var>event</var>'s <code data-x="dom-MouseEvent-button">button</code> attribute is not
1, then return.</p></li>

<li><p>Run the <span>show popover</span> algorithm given <var>select</var>'s <span>select
popover</span>, false, and <var>select</var>.</p></li>
</ol>

<p>If the <code>select</code> is being rendered as a <span>drop-down box</span> with <span>base
appearance</span>, then the user agent should allow the user to <dfn>focus another option</dfn>
given the new <code>option</code> element to focus <var>option</var> and a <code
data-x="event-keydown">keydown</code> event <var>event</var>:</p>

<ol>
<li><p>If <var>event</var>'s <span>canceled flag</span> is set, then return.</p></li>

<li><p>Run the <span>focusing steps</span> on <var>newOption</var>.</p></li>
</ol>

<p class="note">Implementations commonly allow the user to focus the next or previous option via
the arrow-up and arrow-down keys, focus the first or last option via the Home or End keys, or
focus the first or last option in the viewport of the picker via the PageUp or PageDown keys.</p>

<p class="note">Which particular keys of the keyboard cause these actions might differ across
implementations and platforms. The ARIA Authoring Practices Guide has good recommendations for
this behavior <a
href="https://www.w3.org/WAI/ARIA/apg/patterns/combobox/examples/combobox-select-only/">here</a>.</p>

<p>If the <code data-x="attr-select-multiple">multiple</code> attribute is present, and the
element is not <span data-x="concept-fe-disabled">disabled</span>, then the user agent should
allow the user to <dfn data-x="concept-select-toggle">toggle</dfn> the <span
Expand All @@ -53877,6 +53948,9 @@ interface <dfn interface>HTMLSelectElement</dfn> : <span>HTMLElement</span> {
<ol>
<li>Set the <code>select</code> element's <span>user validity</span> to true.</li>

<li><p>Run <span>clone selected <code>option</code> into <code>select</code> button</span> given
the <code>select</code> element.</p></li>

<li><p><span data-x="concept-event-fire">Fire an event</span> named <code
data-x="event-input">input</code> at the <code>select</code> element, with the <code
data-x="dom-Event-bubbles">bubbles</code> and <code data-x="dom-Event-composed">composed</code>
Expand Down Expand Up @@ -54578,6 +54652,24 @@ interface <dfn interface>HTMLOptionElement</dfn> : <span>HTMLElement</span> {

</div>

<p>To <dfn>clone selected <code>option</code> into <code>select</code> button</dfn>, given a
<code>select</code> element <var>select</var>:</p>

<ol>
<li><p>Let <var>option</var> be the first element of <var>select</var>'s <span
data-x="concept-select-option-list">option list</span> whose <span
data-x="concept-option-selectedness">selectedness</span> is set to true, if such an element
exists; otherwise null.</p></li>

<li><p>Let <var>text</var> be the empty string.</p></li>

<li><p>If <var>option</var> is not null, then set <var>text</var> to <var>option</var>'s <span
data-x="dom-option-label">label</span>.</p></li>

<li><p>Set <var>select</var>'s <span>select fallback button text</span> to
<var>text</var>.</p></li>
</ol>

<dl class="domintro">
<dt><code data-x=""><var>option</var>.<span subdfn data-x="dom-option-selected">selected</span></code></dt>

Expand Down Expand Up @@ -59848,7 +59940,8 @@ fur

<p>A <code>form</code> element's <dfn>default button</dfn> is the first <span
data-x="concept-submit-button">submit button</span> in <span>tree order</span> whose <span>form
owner</span> is that <code>form</code> element.</p>
owner</span> is that <code>form</code> element and who is not slotted into a <code>select</code>
element's <span>select button slot</span>.</p>

<p>If the user agent supports letting the user submit a form implicitly (for example, on some
platforms hitting the "enter" key while a text control is <span>focused</span> implicitly submits
Expand Down Expand Up @@ -138026,12 +138119,63 @@ progress { appearance: auto; }</code></pre>
with the element's <code>optgroup</code> element <span data-x="concept-tree-child">children</span>
providing headers for groups of options where applicable.</p>

<p><code>select</code> elements which render as a <span>drop-down box</span> support a <span>base
appearance</span> in addition to <span>native appearance</span> and <span>primitive
appearance</span>.</p>

<p>The <code>select</code> element's <span>select popover</span> supports a <span>base
appearance</span> and a <span>native appearance</span>. The <span>select popover</span> can only
be rendered with <span>base appearance</span> if its associated <code>select</code> is being
rendered with <span>base appearance</span>.</p>

<p>When a <code>select</code> is being rendered as a <span>drop-down box</span> with <span>base
appearance</span>, it is expected to render with a <span>shadow tree</span> that contains the
following elements:</p>

<ol>
<li><p>A <dfn>select button slot</dfn>, which is a <code>slot</code> element. It is appended to
the <code>select</code>'s <span>shadow root</span> as the first child. It is expected to take the
first child element of the <code>select</code> if the first child element is a
<code>button</code>, otherwise the <span>select fallback button text</span>.</p></li>

<li><p>A <dfn>select fallback button text</dfn>, which is a <code>div</code> element. It is
appended to the <span>select button slot</span>.</p></li>

<li><p>A <dfn>select popover</dfn>, which is a <code>div</code> element. It is appended to the
<code>select</code>'s <span>shadow root</span> as the second child, after the <span>select button
slot</span>. The <code>select</code> element's <span>picker pseudo-element</span> is the
<span>select popover</span>.</p></li>

<li><p>A <dfn>select popover slot</dfn>, which is a <code>slot</code> element. It is appended to
the <span>select popover</span>. It is expected to take all child nodes of the
<code>select</code> except for the first child <code>button</code>, which is taken by the
<code>select button slot</code>.</p></li>
</ol>

<p class="note">Since <span>base appearance</span> is determined by computing style, it isn't
possible to swap this DOM structure when switching appearance. Implementations can always include
the DOM structure for <span>base appearance</span> when the <code>select</code> is rendered as a
<span>drop-down box</span> and then choose to include or exclude it from the layout tree in order
to control whether it gets rendered or not.</p>

<p class="note">The <span>select popover</span> is only rendered when it is opted in to <span>base
appearance</span> separately from the <code>select</code> element. Otherwise, a native picker is
used.</p>

<p>The <span>select popover</span>'s <span>implicit anchor element</span> is its associated
<code>select</code> element.</p>

<p>An <code>optgroup</code> element is expected to be rendered by displaying the element's <code
data-x="attr-optgroup-label">label</code> attribute.</p>

<p>An <code>option</code> element is expected to be rendered by displaying the element's <span
data-x="concept-option-label">label</span>, indented under its <code>optgroup</code> element if it
has one.</p>
has one. If the <code>option</code> is in a <code>select</code> which is being rendered as a
<span>drop-down box</span> with <span>base appearance</span>, and the <code>select</code>'s
<span>select popover</span> is being rendered with <span>base appearance</span>, and the
<code>option</code>'s <code data-x="attr-option-label">label</code> attribute is not set, then the
<code>option</code> is expected to render all of its children rather than by displaying its <span
data-x="concept-option-label">label</span>.</p>

<p>Each sequence of one or more child <code>hr</code> element siblings may be rendered as a single
separator.</p>
Expand Down Expand Up @@ -145533,6 +145677,9 @@ INSERT INTERFACES HERE
<dt id="refsCSSFONTS">[CSSFONTS]</dt>
<dd><cite><a href="https://drafts.csswg.org/css-fonts/">CSS Fonts</a></cite>, J. Daggett. W3C.</dd>

<dt id="refsCSSFORMS">[CSSFORMS]</dt>
<dd><cite><a href="https://w3c.github.io/csswg-drafts/css-forms/">CSS Forms</a></cite>, T. Nguyen. W3C.</dd>

<dt id="refsCSSFLEXBOX">[CSSFLEXBOX]</dt>
<dd><cite><a href="https://drafts.csswg.org/css-flexbox/">CSS Flexible Box Layout</a></cite>, T. Atkins, E. Etemad, R. Atanassov. W3C.</dd>

Expand Down