Skip to content
75 changes: 66 additions & 9 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -148350,8 +148350,37 @@ progress { appearance: auto; }</code></pre>
<p>The <span>'::checkmark'</span> pseudo-element only applies to <code>option</code> elements
which are <span data-x="option-base-appearance">being rendered with base appearance</span>.</p>

<p>An <code>optgroup</code> element is <span>expected</span> to be rendered by displaying the
element's <code data-x="attr-optgroup-label">label</code> attribute.</p>
<p>An <code>optgroup</code> element is <dfn data-x="optgroup-base-appearance">rendered with base
appearance</dfn> if it has an <span>ancestor</span> <code>select</code> element, and the nearest
<span>ancestor</span> <span><code>select</code>'s <code>option</code>s are being rendered with
base appearance</span>.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we talking about option elements here? An optgroup can't have option element ancestors, can it? Can we reference the existing definition for nearest ancestor select element?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did this in order to reuse the algorithm which determines when the elements inside a select besides the option are being rendered with base appearance: https://html.spec.whatwg.org/multipage/rendering.html#select's-options-are-being-rendered-with-base-appearance

I removed the word option from the algorithm to make that more clear. How does it look now?


<p>If an <code>optgroup</code> element is not being <span
data-x="optgroup-base-appearance">rendered with base appearance</span>, then it is
<span>expected</span> to be rendered by displaying the element's <span
data-x="concept-optgroup-label">label</span>.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think if we're not fixing this here we should add an XXX marker as this is clearly broken.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, i added an XXX


<p>If an <code>optgroup</code> element is being <span data-x="optgroup-base-appearance">rendered
with base appearance</span>, then it is <span>expected</span> to render with a <span>shadow
tree</span> that contains the following elements:</p>

<ol>
<li><p>An <dfn>optgroup legend slot</dfn>, which is a <code>slot</code> element. It is appended
to the <code>optgroup</code>'s <span>shadow root</span> as the first child. It is
<span>expected</span> to take the first child element of the <code>optgroup</code> if the first
child element is a <code>legend</code> element.</p></li>

<li><p>An <dfn>optgroup label element</dfn>, which is a <code>div</code> element. It is appended
to the <span>optgroup legend slot</span> as the first child. It is <span>expected</span> to
Comment thread
josepharhar marked this conversation as resolved.
Outdated
contain a copy of the text in the <code>optgroup</code>'s <code
data-x="attr-optgroup-label">label</code> attribute.</p></li>

<li><p>An <dfn>optgroup slot</dfn>, which is a <code>slot</code> element. It is appended to the
Comment thread
josepharhar marked this conversation as resolved.
Outdated
<code>optgroup</code>'s <span>shadow root</span> after the <span>optgroup label element</span>.
It is <span>expected</span> to take all child nodes of the <code>optgroup</code>
Comment thread
josepharhar marked this conversation as resolved.
Outdated
element except for the first child <code>legend</code> element, if present, which is taken by the
<span>optgroup legend slot</span>.</p></li>
</ol>

<div algorithm>
<p>To determine if a <dfn><code>select</code>'s <code>option</code>s are being rendered with base
Expand All @@ -148375,13 +148404,31 @@ progress { appearance: auto; }</code></pre>
ancestor <code>select</code></span> and the <span><code>select</code>'s <code>option</code>s are
being rendered with base appearance</span>.</p>

<p>An <code>option</code> element is <span>expected</span> to be rendered by displaying the result
of <span>collect option text</span> given the <code>option</code> and true, indented under its
<code>optgroup</code> element if it has one. If the <code>option</code> <span
data-x="option-base-appearance">is being rendered with 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 <span>expected</span> to render all of its children rather than by
displaying its <span data-x="concept-option-label">label</span>.</p>
<p>If an <code>option</code> element is not being <span data-x="option-base-appearance">rendered
with base appearance</span>, then it is <span>expected</span> to be rendered by displaying the
result of <span>collect option text</span> given the <code>option</code> and true.</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we first have to define what it means for an option element to be rendered with base appearance as base/native appearance isn't a thing for option elements (aiui). So the same order as above for optgroup with probably the same set of comments.

If we also tackle option we need to update the PR to make that clear.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So should I add a <p class="XXX"> saying that option elements need their native and primitive appearance to be specified?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That probably has to happen as well then, yes.

My preferred solution would be that we just define it as part of select's native appearance, but it seems that's not possible given how Chromium does things here and maybe Gecko?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took another look and I'm not sure what the option element is missing that the optgroup element has with regards to base/native appearance in this PR. Could you elaborate on what is missing?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For optgroup we start out with defining what it means to be rendered with base appearance. For instance, we require an ancestor select (though we need to make that more precise so it deals with intermediate hr elements and the like I think).

I'm not sure that is sufficient however as these don't really have base appearance through appearance: base. It's a result of nesting, right? So I'm not sure that makes them compatible with the appearance base infra.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what we want is that some things apply universally, such as display: block and some things are conditional upon the nearest ancestor select's computed/used appearance. Because I don't think we can say that option elements themselves have any kind of appearance, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what we want is that some things apply universally, such as display: block and some things are conditional upon the nearest ancestor select's computed/used appearance.

Yes, that makes sense. I took a look at chromium, and the only UA style rule that is applied to option elements in both appearance:auto and appearance:base selects is white-space:nowrap, which maybe is another thing we just need to undo for "base appearance".

Because I don't think we can say that option elements themselves have any kind of appearance, right?

Yes, option elements don't support the appearance property. If you think we should rename this definition for options and optgroup elements, I'd be happy to rename it.

Copy link
Copy Markdown
Member

@annevk annevk Apr 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

white-space:nowrap is currently non-standard. Does Gecko have that?

WebKit is adding display: block to both option and optgroup elements, and font-weight: bolder for optgroup, but that's it thus far (https://commits.webkit.org/311911@main). We should make the user agent style sheet reflect at least that.

As for the language, maybe something like "option/optgroup elements [with a base appearance select]" and then "with a base appearance select" is defined through the ancestor select element thingy that also handles hr elements and the like and requires the select element to have base appearance?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

white-space:nowrap is currently non-standard. Does Gecko have that?

It is standardized for base appearance: https://html.spec.whatwg.org/multipage/rendering.html#:~:text=0.5em%3B-,white%2Dspace%3A%20nowrap,-%3B%0A%7D%0A%0Aselect

WebKit is adding display: block to both option and optgroup elements, and font-weight: bolder for optgroup, but that's it thus far (https://commits.webkit.org/311911@main). We should make the user agent style sheet reflect at least that.

Thanks, I see that this is about UA styles for options and optgroups when they are outside of a select element, not about base appearance. I'd be supportive of standardizing/changing those styles as long as there aren't compat issues. Maybe that's worth a separate spec issue and PR?

I added properties like white-space:nowrap to the base appearance section because I didn't think that we would actually standardize the UA styles for these elements outside of base appearance.

As for the language, maybe something like "option/optgroup elements [with a base appearance select]" and then "with a base appearance select" is defined through the ancestor select element thingy that also handles hr elements and the like and requires the select element to have base appearance?

Ok, I used the shared algorithm to find an ancestor select, and I'm still using the shared algorithm which defines when select's contents are rendered with base appearance. How does it look?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this works overall. I think we should probably keep things restricted to the base appearance style sheet if they are not universal, but if we can agree on making them universal we should move them. I think that's the case for display: block and font-weight at least.


<p>If an <code>option</code> element is being <span data-x="option-base-appearance">rendered
with base appearance</span>, then it is <span>expected</span> to render with a <span>shadow
tree</span> that contains the following elements:</p>

<ol>
<li><p>An <dfn>option label element</dfn>, which is a <code>div</code> element. It is appended to
the <code>option</code>'s <span>shadow root</span> as the first child. It is
<span>expected</span> to have a text node child containing the value of the <code>option</code>'s
<code data-x="attr-option-label">label</code> attribute. If the <code>option</code> element does
not have the <code data-x="attr-option-label">label</code> attribute, or the <code
data-x="attr-option-label">label</code> is set to an empty string, then the <span>option label
element</span> is <span>expected</span> to have its <span>'display'</span> property set to
'none'.</p></li>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So why not have this as a child of the slot element and then determine whether we slot things into the slot or not based on the condition of the label attribute? I thought that was the direction we were heading in.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I rewrote it to use slot assignment and a fallback instead


<li><p>An <dfn>option content slot</dfn>, which is a <code>slot</code> element. It is appended to
the <code>option</code>'s <span>shadow root</span> as the second child. It is
<span>expected</span> to take all child nodes of the <code>option</code> element. If the
<code>option</code> has the <code data-x="attr-option-label">label</code> attribute set to any
value besides the empty string, then the <span>option content slot</span> is
<span>expected</span> to have its <span>'display'</span> property set to 'none'.</p></li>
</ol>

<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 @@ -148555,6 +148602,16 @@ select {
block-size: calc(max(24px, 1lh) * attr(size type(&lt;integer>), 4));
}</code></pre>

<p>The following styles are <span>expected</span> to apply to the <span>optgroup label
element</span> when its parent <code>optgroup</code> element is being <span
data-x="optgroup-base-appearance">rendered with base appearance</span>:</p>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just make these unconditional based on select optgroup?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the shadow tree is conditional upon a select with base appearance so there is no optgroup label element without that.


<ul>
<li><p><code data-x="" class="css">padding-inline: 0.5em</code></p></li>

<li><p><code data-x="" class="css">min-block-size: 1lh</code></p></li>
</ul>

<div w-nodev>

<h4>The <code>textarea</code> element</h4>
Expand Down