Skip to content

Update: legend to provide name to optgroup#2360

Open
scottaohara wants to merge 10 commits into
mainfrom
select-legend-optgroup
Open

Update: legend to provide name to optgroup#2360
scottaohara wants to merge 10 commits into
mainfrom
select-legend-optgroup

Conversation

@scottaohara
Copy link
Copy Markdown
Member

@scottaohara scottaohara commented Oct 22, 2024

In regards to the updated content model for the select element and its allowed children, an optgroup can have a legend element as its first child, and this legend needs to be able to name the optgroup similarly to how a legend names a fieldset.

see:
whatwg/html#10586

WPT - web-platform-tests/wpt#49645

Test, Documentation and Implementation tracking

Once this PR has been reviewed and has consensus from the working group, tests should be written and issues should be opened on browsers. Add N/A and check when not applicable.

  • "author MUST" tests: n/a
  • "user agent MUST" tests:
  • Browser implementations (link to issue or commit):
    • WebKit:
    • Gecko: endorsed for implementation
    • Blink: implemented
  • Does this need AT implementations? n/a
  • Related APG Issue/PR:
  • MDN Issue/PR:

In regards to the updated content model for the select element and its allowed children, an `optgroup` can have a `legend` element as its first child, and this `legend` needs to be able to name the `optgroup` similarly to how a `legend` names a `fieldset`.

see:
whatwg/html#10586
@netlify
Copy link
Copy Markdown

netlify Bot commented Oct 22, 2024

Deploy Preview for wai-aria ready!

Name Link
🔨 Latest commit 833507c
🔍 Latest deploy log https://app.netlify.com/projects/wai-aria/deploys/6939f1e65a809b00086fa4e8
😎 Deploy Preview https://deploy-preview-2360--wai-aria.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

open question in whatwg/html#10586 (comment) about what should take priority - legend or optgroup's label attr.

if both end up being allowed / render - then one of these could be added to the accDescription computation - instead of ignoring one or combining them into one long name.
@jnurthen jnurthen requested a review from keithamus October 24, 2024 17:16
@scottaohara scottaohara marked this pull request as draft October 24, 2024 17:19
Copy link
Copy Markdown
Member

@keithamus keithamus left a comment

Choose a reason for hiding this comment

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

Couple of minor formatting comments, but this LGTM from a spec position, modulo new resolutions from the WHATWG.

Comment thread html-aam/index.html Outdated
Comment thread html-aam/index.html Outdated
Co-authored-by: Keith Cirkel <keithamus@users.noreply.github.com>
Comment thread html-aam/index.html
@scottaohara scottaohara requested a review from keithamus November 1, 2024 19:02
@scottaohara scottaohara marked this pull request as ready for review November 1, 2024 19:02
@scottaohara
Copy link
Copy Markdown
Member Author

@keithamus would you mind taking another look? I've updated the ordering for the optgroup naming, and added new content to how a description should be calculated.

cc @josepharhar as updates here related to my comments in the update content model for customized select PR

@scottaohara
Copy link
Copy Markdown
Member Author

scottaohara commented Nov 1, 2024

examples for tests for how name/desc steps should work

## Name from aria-labelledby and description expectation tests

test 1: name = foo
        description = n/a
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-labelledby=f>
       <div id=f>foo</div> <!-- invalid per content model -->
       <option>test
    </optgroup>
</select>


test 2: name = foo
        description = n/a
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-labelledby=f aria-label=bar>
       <div id=f>foo</div> <!-- invalid per content model -->
       <option>test
    </optgroup>
</select>


test 3: name = foo
        description = bar
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-labelledby=f title=bar>
       <div id=f>foo</div> <!-- invalid per content model -->
       <option>test
    </optgroup>
</select>


## Name from aria-label and description expectation tests

test 1: name = foo
        description = n/a
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-label=foo>
        <option>test
    </optgroup>
</select>

test 2: name = foo
        description = bar
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-label=foo title=bar>
        <option>test
    </optgroup>
</select>



## Name from label attribute and description expectation tests

test 1: name = foo
        description = n/a
<!-- primary use case, no naming mechanism aside from label attribute -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup label=foo>
        <option>test
    </optgroup>
</select>


test 2: name = bar
        description = foo
<!-- aria-label provided which wins out over label attr, but label attr's value is rendered, so still
     expose it as a description so the information is at least still available to AT -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-label=bar label=foo>
        <option>test
    </optgroup>
</select>


test 3: name = foo
        description = bar
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup label=foo title=bar>
        <option>test
    </optgroup>
</select>


## Name from legend element and description expectation tests

test 1: name = foo 
        description = n/a
<!-- primary use case, no naming mechanism aside from legend element -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup>
        <legend>foo</legend>
        <option>test
    </optgroup>
</select>

test 2: name = foo 
        description = n/a
<!-- label attr value is not to render because legend is specified -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup label=bar>
        <legend>foo</legend>
        <option>test
    </optgroup>
</select>

test 3: name = bar 
        description = foo
<!-- aria-label provided which wins out over legend, but legend is rendered, so still
     expose it as a description so the information is at least still available to AT -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-label=bar>
        <legend>foo</legend>
        <option>test
    </optgroup>
</select>

test 4: name = bar 
        description = foo
<!-- aria-labelledby provided which wins out over legend, but legend is rendered, so still
     expose it as a description so the information is at least still available to AT -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-labelledby=b>
        <div id=b>bar</div> <!-- invalid per content model -->
        <legend>foo</legend>
        <option>test
    </optgroup>
</select>


test 5: name = foo 
        description = bar
<!-- legend provides name, title provides description -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup title=bar>
        <legend>foo</legend>
        <option>test
    </optgroup>
</select>


## Name from title attribute and description expectation tests

test 1: name = foo 
        description = n/a
<!-- primary use case, no naming mechanism provided aside from title attribute -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup title=foo>
        <option>test
    </optgroup>
</select>


test 2: name = foo 
        description = n/a
<!-- empty label would otherwise result in no accName - use title as fallback -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup label title=foo>
        <option>test
    </optgroup>
</select>

test 3: name = foo 
        description = n/a
<!-- empty legend would otherwise result in no accName - use title as fallback -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup title=foo>
        <legend></legend>
        <option>test
    </optgroup>
</select>

test 4: name = foo
        description = n/a
<!-- empty aria-label would otherwise result in no accName - use title as fallback -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-label title=foo>
        <legend></legend>
        <option>test
    </optgroup>
</select>

test 5: name = foo
        description = n/a
<!-- aria-labelledby points to empty element which would otherwise result in no accName - use title as fallback -->
<select>
    <button><selectedcontent></selectedcontent></button>
    <optgroup aria-labelledby=f title=foo>
        <div id=f></div>
        <legend></legend>
        <option>test
    </optgroup>
</select>

Copy link
Copy Markdown
Member

@keithamus keithamus left a comment

Choose a reason for hiding this comment

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

Still LGTM

@scottaohara scottaohara marked this pull request as draft November 12, 2024 22:23
@scottaohara
Copy link
Copy Markdown
Member Author

scottaohara commented Nov 12, 2024

put back into the draft state as I need to revise the bits about how a label attribute and legend element should no longer be expected to render at the same time. re: https://issues.chromium.org/issues/378601807

@josepharhar
Copy link
Copy Markdown

put back into the draft state as I need to revise the bits about how a label attribute and legend element should no longer be expected to render at the same time. re: https://issues.chromium.org/issues/378601807

If you have a recommendation for what to do in this case, let me know and/or comment on the crbug. I haven't implemented anything yet to account for the case where both are present.

@scottaohara
Copy link
Copy Markdown
Member Author

@josepharhar i think it's totally fine to only have one render / and have a preference for the legend element in this case since it'll allow for authors to do more.

  • if only label attribute is specified, render that to be consistent with prior select functionality
  • if only legend is specified, render that and if the select is loaded in a browser that doesn't support customization, there is no fallback
  • if both are specified,
    • in browsers that support customization render legend element as the group label and do not render label attribute text
    • in browsers that don't support customization render the fallback label attribute text as the group label

revised to incorporate latest decisions on how the naming/desc should work
@scottaohara scottaohara marked this pull request as ready for review December 11, 2024 20:35
@spectranaut
Copy link
Copy Markdown
Contributor

@scottaohara does this need implementation changes? If so I'll add the PR tracking list.

@spectranaut
Copy link
Copy Markdown
Contributor

Discussed briefly in last weeks meeting: https://www.w3.org/2025/06/26-aria-minutes.html#58a8

@jcsteh
Copy link
Copy Markdown
Contributor

jcsteh commented Dec 10, 2025

Gecko: Keith said this is implemented.

I'm not sure this is true. I don't see anything in the Gecko accessibility code that would currently support legend as a labelling child of optgroup. But maybe I'm missing something. @keithamus, can you clarify your thinking here?

Copy link
Copy Markdown
Contributor

@jcsteh jcsteh left a comment

Choose a reason for hiding this comment

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

Overall, this looks good, but I think it needs some clarifications.

Comment thread html-aam/index.html
<div class="relations"><span class="type">Relations:</span> `IA2_RELATION_LABEL_FOR` with the parent <a href="#el-fieldset">`fieldset`</a></div>
<div class="relations">
<span class="type">Relations:</span> `IA2_RELATION_LABEL_FOR` with the parent <a href="#el-fieldset">`fieldset`</a>
or <a href="#el-optgroup">`optgroup`</a>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

For clarity, I think we need to specify the reverse LABELLED_BY relation somewhere. For example, we do this for fieldset. We're somewhat inconsistent about where we document the relation. For IA2, we document LABELLED_BY in the <fieldset> section, but for UIA, we document LabeledBy in the <legend> section. That's an editorial issue we can sort out separately, but I think it does need to be documented somewhere, and I'd suggest documenting the IA2 relation in the <optgroup> section, since that's what we do for <fieldset>.

Comment thread html-aam/index.html
<span class="type">Relations:</span>
`ATK_RELATION_LABEL_FOR` with parent <a href="#el-fieldset">`fieldset`</a> element
`ATK_RELATION_LABEL_FOR` with parent <a href="#el-fieldset">`fieldset`</a>
or <a href="#el-optgroup">`optgroup`</a> element
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ditto regarding the LABELLED_BY relation.

Comment thread html-aam/index.html
</li>
<li>
or use the <a data-cite="accname-1.2/#mapping_additional_nd_te">text equivalent computation</a> of the subtree of the
first `legend` element if it was not used as the <a data-cite="accname-1.2/#dfn-accessible-name">accessible name</a>.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

We should expose DESCRIBED_BY and DESCRIPTION_FOR relations if we do this. I think we have the same issue for table captions when used as description, but I guess we should address that separately.

@keithamus
Copy link
Copy Markdown
Member

Gecko: Keith said this is implemented.

I'm not sure this is true. I don't see anything in the Gecko accessibility code that would currently support legend as a labelling child of optgroup. But maybe I'm missing something. @keithamus, can you clarify your thinking here?

I don't recall saying it's already implemented, but maybe I did? I'm not sure I can clarify further given that I don't remember.

@scottaohara
Copy link
Copy Markdown
Member Author

I don't recall saying it's already implemented, but maybe I did? I'm not sure I can clarify further given that I don't remember.

looks like Val updated the gecko status back in July. looking back at the minutes, I'm guessing this was just a misunderstanding/typo - as you said chrome implemented, and you were approving of the PR so that it could count as endorsement from mozilla. i've updated the OP to correct this

@scottaohara
Copy link
Copy Markdown
Member Author

thanks for the review on this @jcsteh - i'll work on these suggestions asap

@spectranaut spectranaut moved this from Needs Review to Needs updates from review in ARIA Normative PR Tracking Jan 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Needs updates from review

Development

Successfully merging this pull request may close these issues.

6 participants