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

Inconsistent name calculations for input elements #231

Closed
dd8 opened this issue Aug 8, 2019 · 12 comments
Closed

Inconsistent name calculations for input elements #231

dd8 opened this issue Aug 8, 2019 · 12 comments

Comments

@dd8
Copy link

dd8 commented Aug 8, 2019

input type=number

input type=number works like an (enhanced) edit box and displays placeholders, but isn't listed in 5.1 so falls back to the calculation in 5.7 Other Form Elements which doesn't use the placeholder attribute:

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number#Additional_attributes

Multiple labels

The name calculation for Input types listed in 5.1 explicitly accounts for multiple labels:

  1. Otherwise use the associated label element(s) accessible name(s) - if more than one label is associated; concatenate by DOM order, delimited by spaces.

but the name calculation for 5.7 Other Form Elements (e.g. type=week, type=datetime-local) says:

  1. Otherwise use label element.

(There might be reasons to treat type=radio and type=checkbox differently, but edit box replacements like type=week should probably allow multiple labels)

Typo

Editorial: input type='email is listed in 5.1.1 and 5.1.2 but is missing from the 5.1 heading

5.1 input type="text", input type="password", input type="search", input type="tel", input type="url" and textarea Element
5.1.1 input type="text", input type="password", input type="search", input type="tel", input type="email", input type="url" and textarea Element Accessible Name Computation
5.1.2 input type="text", input type="password", input type="search", input type="tel", input type="email", input type="url" and textarea Element Accessible Description Computation

https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-url-and-textarea-element

@scottaohara
Copy link
Member

Thank you @dd8

I've been working on updating content that would address the points you raise here, which are related to existing issues #209, #134, #225, #210.

This issue will be noted in that update, however I'd be more than happy to accept a PR to address these more immediately, as everything you've listed are really editorial updates to match reality.

@dd8
Copy link
Author

dd8 commented Aug 12, 2019

I'd be more than happy to accept a PR to address these more immediately

@scottaohara We've just completed an green field implementation of accname-1.1/html-aam and noted a number of problems with both specs. Would you be interested in some suggestions / PRs?

@scottaohara
Copy link
Member

i'd be interested in your findings, sure. especially since i'd be interested to see if i'm missing anything from the work i've been drafting.

@dd8
Copy link
Author

dd8 commented Aug 12, 2019

One of the main problems we found is the flow of control between accname-1.1 and html-aam is not obvious and there seems to be duplication of some steps:

https://w3c.github.io/accname/#mapping_additional_nd_te

https://w3c.github.io/html-aam/#input-type-text-input-type-password-input-type-search-input-type-tel-input-type-email-input-type-url-and-textarea-element-accessible-name-computation

For example, to calculate name of this input field:

<label for='city'>City:<label><input type='text' id='city' />

AccName
Step 1 - initialise
Step 2A - if hidden and not referenced return empty string
Step 2B - if aria-labelledby set return accnames for IDREFs in aria-labelledby
Step 2C - if aria-label set return that
Step 2D - if node is not presentational compute native name using html-aam, and if set return that
5.1.1 1. if has aria-label or aria-labelledby compute using AccName (already done above)
5.1.1 2. otherwise use the associated label element(s) accname(s)
5.1.1 3. If the accessible name is still empty, then: use the control's title attribute.
5.1.1 4. Otherwise use the control's placeholder attribute
5.1.1 5. Otherwise accname is empty
Step 2E - if current node is a control embedded in another controls label return control value
Step 2F - compute name from content
Step 2G - if current node is a text node return that
Step 2H - if current node is descendant of root node jump to 2F i)
Step 2I -if tooltip set (i.e. title attribute) return that (already done in 5.1.1.3 above)

There's mutual recursion between html-aam and accname, but the entry points to the algorithms aren't clear due to duplication. This leads to weird inconsistencies - for example:

role='presentational' affects the use of the title attribute in calculations at step 2D but not at step 2I. The same happens with aria-label and aria-labelledby at 2B/2C and 5.1.1 1.

I think there's an easy way to avoid duplication and make the flow of control clearer using the approach that css-syntax-3 uses - it has well-defined entry points intended for other specs: https://www.w3.org/TR/css-syntax-3/#parser-entry-points.

For accname/html-aam you could have entry points like these:

  • accname-1.1: calculate an accessible name (called by html-aam for label contents)
  • accname-1.1: calculate an accessible description
  • html-aam: calculate a native name (called by accname step 2D)
  • html-aam: calculate a native description

@dd8
Copy link
Author

dd8 commented Aug 12, 2019

Some of the accname unit tests depend on the correct calculation for aria-owns but I can't see anything specifies how aria-owns is used (e.g. do the names calculated for aria-owns elements come before or after the name of the element with the aria-owns attribute)

Edit: Order is specified in https://www.w3.org/TR/wai-aria-1.1/#aria-owns, but I think the accname calc should specify where aria-owns nodes are used in the calculation (probably in Step 2F - compute name from content)

@dd8
Copy link
Author

dd8 commented Aug 12, 2019

accname-1,1: Otherwise, if the current node is a descendant of an element whose Accessible Name or Accessible Description is being computed, and contains descendants, proceed to 2F.i.

It's not clear if this is a goto or a function call of steps 2F.i) through 2F.iv)

css-syntax-3 handles this type of situation by splitting the CSS parsing algorithm into simple algorithms that call one another:
https://www.w3.org/TR/css-syntax-3/#parse-stylesheet

@scottaohara
Copy link
Member

scottaohara commented Aug 12, 2019

Hi Mark,

Going to try to respond to all your questions/points starting from your first post on, but at a high level I agree with you that there could be some wording to make it more clear when to defer to one spec over the other.

HTML AAM notes that step one is to reference steps 2b/2c of accName. This is not meant as a duplicative effort, rather HTML is deferring to steps 2b/2c of accName if aria-label or labelledby are used as they are naming mechanisms not part of the HTML host language.

Specifically looking at the example you presented, the algorithm would stop after step 5.1.1 step 2 (label), so nothing beyond that would be considered since the label would provide the accessible name.

But if we were to look at a nameless input as if the specs were combined as you did in your first post, then the algorithm would behave like:

1 . initialize
2a. if hidden and not referenced return empty string ( keep going )
2b. otherwise if aria-labelledby... ( keep going )
2c. otherwise if aria-label ( keep going )
2d. otherwise if not presentational and native HTML element, go to HTML-AAM ( OK, go to HTML AAM )
5.1.1 - 1. (a reference to running 2b/c so this step is not acted on)
5.1.1 - 2. otherwise use label element ( keep going )
5.1.1 - 3. otherwise use title attribute ( keep going )
5.1.1 - 4. otherwise use placeholder attribute ( keep going )
5.1.1 - 5. otherwise no accessible name ( stop as there is no accessible name )

steps 2e - 2i are not run because HTML AAM returned no accessible name.

For accName, if the role does not come from a native HTML element, HTML AAM would be skipped over and naming would resume with 2e.

Now, regarding aria-owns, while not mentioned in HTML AAM (because it's not HTML) to name the input in your example it would need to be used on the label element, and reference another element from where to grab a text string in the DOM. If that returned something, the naming algorithm would still cover that under 5.1.1 step 2 (label element).

Hope that helps.

@dd8
Copy link
Author

dd8 commented Aug 15, 2019

@scottaohara Thanks - that's helpful. Looks like there's already an open issue for aria-owns which flags up various interop issues and inconsistencies in implementations:
w3c/accname#25

@dd8
Copy link
Author

dd8 commented Aug 15, 2019

Another apparent inconsistency is the treatment of steps that can return an empty string or whitespace. An aria-label='' or aria-label=' ' is explicitly ignored by 2C, but other steps don't say if an empty string should be ignored or used

So whether this stops at 2B returning an empty label, or proceeds to 2C and returns 'Test1' is probably implementation dependant:

<input aria-labelledby='blankId' aria-label='Test1' alt='Test2' type='image'> 
<span id='blankId'> <span>

but the spec explicitly says this should continue to 2D:

<input aria-label=' ' alt='Test2' type='image'> <span id='blankId'> <span>

From an implementors standpoint, it's easier to check for an empty string before executing the next step, than checking in advance whether all the conditions for each step are satisfied (although this might need special casing for alt=''). So in pseudo-code:


functon GetAccName( current_node )
{
// 2B
result = GetAccNameFromIdRefs( current_node, "aria-labelledby" );

// 2C
if ( result == '' )
 result = GetAccNameFromAttribute( current_node, "aria-label" );

// 2D
if ( result == '' )
 result = GetNativeAccName(current_node);

// other steps
}

function GetAccNameFromIdRefs( current_node, attribute_name )
{
 if ( !HasAttribute( current_node, attribute_name )
  return "";

// get nodes referred to by attribute_name
}

@scottaohara
Copy link
Member

hmm.

i can confirm, as i've run into this issue lately, that instances of <img src="..." alt=" "> have definitely resulted in what was meant to be decorative images exposed as being named.

@stevefaulkner we should have a think on this :)

@dd8
Copy link
Author

dd8 commented Aug 23, 2019

@scottaohara Some more info - this accname test case doesn't work unless white space is trimmed from the result of name-from-content:
https://github.com/web-platform-tests/wpt/blob/master/accname/name_test_case_602-manual.html

If the result isn't trimmed you get the accName calculated from the <div> content of a newline and 2 spaces.

IMO it makes sense to trim the result for each step - not just aria-label. The only place that might matter is the difference between alt='' and alt=' ' but the null alt should already be mapped to role=presentation before the AccName calculation runs

Most of the time it won't make any difference, but it does stop white-space only names being returned in cases like name_test_case_602

@scottaohara
Copy link
Member

closing this issue due to the other linked issues that are related, and the PR #239 which will aim to resolve the white space issue that is also noted here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants