w3c / html-aam

HTML Accessibility API Mappings
https://w3c.github.io/html-aam/
Other
97 stars 25 forks source link

Clarify hidden elements do not return name #533

Closed scottaohara closed 1 week ago

scottaohara commented 4 months ago

closes #370

Adds comments to label, legend and caption elements to indicate that if they are hidden, then they will not return a name for their associated elements.

Note that right now this means that

<label for=d hidden>foo</label>
<input id=d title=bar>

has no name. The label is still referenced, but because it is hidden it returns an empty name in Safari and Chromium browsers. Firefox correctly returns "bar" as the name of the input.

I think this can probably be made more clear in the naming steps, and I can make some wpts for this... i'm just not sure exactly where to put them now without potentially overlapping or ballooning out some of the existing tests. probably worth talking about that when we triage this.

The PR also includes some consistency cleanup for legend/caption.

Implementation


Preview | Diff

scottaohara commented 4 months ago

to be clear, the stuff i was really hoping for discussion on with the review of this PR was things like should hidden labels/legends/captions continue to even be associated with their respective elements, if they are hidden? And thus, returning no name.

The example i brought up on the call was

<label hidden for=f>foo</label>
<input id=f title=blargh>

where the above example applies to tables and fieldsets with captions and legends, respectively.

there is inconsistency in how the above is treated. where some browsers return an empty name for the input. And I believe I said it was Firefox returns "blargh" as the name of the input.

based on what this spec already has written for how these elements are named (input naming as an example)

  • Otherwise use the associated label element or elements accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.
  • If the accessible name is still empty, then: use the control's title attribute.

My understanding is that Firefox is doing the right thing, and chromium/webkit are incorrectly stopping with the returned empty string from the hidden label/caption/legend.

But since 2 browsers aren't following what the spec says, I am doubting myself if there's somehow a lack of clarity here.

adampage commented 4 months ago

I agree, the “If empty, then...” statements are unambiguous and Firefox is doing the right thing.

In contrast, 4.1.2 has a more wobbly “Otherwise, if the control still has no accessible name use title attribute”. For this one, Chrome and Webkit could argue that the control does have an accessible name, it just happens to be empty.

Looking down the list of elements, I also see input[type="image"] has “Otherwise use title attribute if present and its value is not the empty string”, where the “otherwise” is similarly ambiguous. When step 1’s “If the control has an... aria-labelledby...” condition has been satisfied (even if the returned accname is empty), then implementers could be forgiven for thinking they can skip the rest?

So it does seem like there’s an opportunity to normalize all of the elements to that “if empty” phrasing so that title is always reliably used as the last resort.

adampage commented 4 months ago

The figure’s name computation of:

  1. If...
  2. If still empty...
  3. If still empty...
  4. Otherwise

...reads crystal clear to me. If you think normalizing all the 4.1 elements to this pattern would be sensible, I’d be happy to take a stab at that as a separate PR, and also add some more WPT tests for the title business.

fstrr commented 4 months ago

Agree that Firefox is doing the right thing in using the title attribute.

Adam's suggestion to Normalize the 4.1 content to match the figure element's steps is a good idea.

scottaohara commented 4 months ago

i say let's just get that input consistency into this PR.

we should probably do another PR / tests for the following, though

the table/fieldset already seem like they're clear at first glance. but from what i've seen one could have

<fieldset>
  <legend hidden>foo</legend> <!-- this returns no name, so fieldset has no name -->
  <legend>test</legend> <!-- this is rendered as if there is no previous legend.  but it doesnt' contribute to name -->
</fieldset>

where the initial legend is hidden and an 'invalid' second legend is rendered instead. visually, this looks just fine, but the accName calc stops at the hidden legend, and doesn't get to the actually rendered legend to get a name from that. Is that actually what people expect should happen here?

adampage commented 4 months ago

Yeah, I see. Since the browser goes ahead and permissively renders that invalid second <legend>, the accname mapping should have equivalence. 😐

...if the fieldset element has a child that is a legend element, then use the subtree of the first such element.

In the above step from 4.1.5, “the first such element” is plainly specific but also suggests a tolerance for multiple legend elements even while HTML prohibits it.

An allowance for invalid multi-legend/caption scenarios could look something like:

...if the fieldset element has a child that is a legend element and is exposed to the accessibility tree, then use the subtree of the first such element.

I guess we’re basically just doing our best to imitate whatever error correction algorithm that browsers are doing for rendering invalid HTML. Which I suppose is — please forgive my naivete — not standardized, or at least not specified anywhere that we could reference or copy?

scottaohara commented 1 week ago

closing as now being handled in aria PR 2214