aria
aria copied to clipboard
Clarify "undefined" assignment for a state/property as the value (not the string)
Describe the change
In order to address https://github.com/w3c/aria/issues/2156, @spectranaut /@smhigley /@aardrian suggested clarification in the spec of how to assign undefined for states and properties; namely, to clarify that undefined represents a value (e.g., aria-expanded=undefined) rather than a string (e.g., aria-expanded="undefined"). This change may also involve explicitly stating the absence of a value is equivalent to undefined.
It's unclear where this should be documented (perhaps Section 6.2 Characteristics of States and Properties).
Unconventional techniques for assigning an undefined value
There may need to be additional clarification on the following assignment methods:
- Empty string:
stateOrProperty = ""(this one is referenced in thearia-currentsection as being allowed via the empty string, i.e., "If the attribute is not present or its value is the empty string...") - Null:
stateOrProperty = null
Potentially erroneous spec examples of "undefined" string value
The following two undefined references use the string value which may be confusing and require updating:
When exposing as a platform API Boolean state: For values of "" (empty string), "undefined" or no attribute present:
NOTE As of ARIA 1.3, aria-hidden="false" is now synonymous with aria-hidden="undefined".
Validator testing of undefined vs. "undefined"
W3C HTML Validator shows the following parsing results when undefined is assigned as a value (stateOrProperty=undefined) vs. a string (stateOrProperty="undefined").
For states/properties that support explicit assignment of undefined:
| State/property | "undefined" string |
undefined value |
Tested elements |
|---|---|---|---|
aria-checked |
passes | passes | role="checkbox", role="radio" |
aria-current (may be missing undefined in its Values table, see https://github.com/w3c/aria/issues/2176) |
fails | fails | <button>, <a>, role="button", role="link" |
aria-expanded |
passes | passes | <button>, <a>, role="button", role="link" |
aria-grabbed |
Not tested | Not tested | None (deprecated element) |
aria-hidden (very recently added as part of https://github.com/w3c/aria/pull/2090) |
fails | fails | <button>, <a>, role="button", role="link" |
aria-orientation |
passes | passes | role="scrollbar", "role="slider", role="tablist" |
aria-pressed |
passes | passes | <button>, role="button" |
aria-selected |
passes | passes | role="tab" |
aria-multiselectable (may be missing undefined in its Values table, see https://github.com/w3c/aria/issues/2176) |
fails | fails | role="tablist", role="listbox" |
Link to the version of the specification or documentation you were looking at
Link to documentation: https://w3c.github.io/aria
Does the issue exists in the editors draft (the editors draft is the most recent draft of the specification)?
Yes.
@rahimabdi could you clarify how you're testing the not-string undefined value with the W3C HTML validator? I'm definitely not getting failures for HTML like <button>some text</button> (i.e. with no attribute defined), and I don't believe the validator is looking at scripting or setting of IDL attributes. Some of the things you have marked as failures under the "undefined value" column are kinda throwing me a bit 😅
Also dropping this here as well (I posted it in a reply comment in a PR, but thought it'd be easier to find here too):
I made a test page to output the browser-mapped values when ARIA attributes are set to the string "undefined", not set at all, or set programmatically to undefined: https://jsfiddle.net/pobwvgs9/
I checked it in Chrome, Edge, Safari, and Firefox on macOS and Windows (Safari only on mac), and all of them had the same not-undefined results for the string "undefined". The results for not-defined and programmatic = undefined values are what I'd expect & what matches the spec, while the string "undefined" are not.
Discussed briefly during the ARIA working group meeting: https://www.w3.org/2024/05/16-aria-minutes#t09
Consensus that the string "undefined" should not be considered undefined.
@rahimabdi could you clarify how you're testing the not-string
undefinedvalue with the W3C HTML validator? I'm definitely not getting failures for HTML like<button>some text</button>(i.e. with no attribute defined), and I don't believe the validator is looking at scripting or setting of IDL attributes. Some of the things you have marked as failures under the "undefined value" column are kinda throwing me a bit 😅
@smhigley For the undefined assignment (not the string), I took each of the state/properties and set it as follows: stateOrProperty=undefined, e.g., aria-expanded=undefined. I've never implemented these in this manner, or seen them implemented this way, but the spec language (and HTML Validator) seem to be OK with it.
I think the spec may benefit from greater clarity on what it means for a state/property to be undefined, and to delaminate all the ways something can be undefined. I counted the following techniques:
- stateOrProperty="undefined" (the ARIA WG agrees this is invalid)
- stateOrProperty=undefined
- stateOrProperty=null
- stateOrProperty="" (empty string)
- stateOrProperty (without an assignment, e.g.,
aria-current). Does this one need a default value?
I am on board with consistency within the spec itself. Are you proposing a PR to do so?
Otherwise I cannot tell from your comment what you feel the next step should be.
Do I understand it correctly: PROPERTY=undefined and PROPERTY is not set results in the value undefined; and PROPERTY="undefined" or PROPERTY="" is not undefined.
If so we should correct it in the specs.
ARIA WG "undefined" deep dive meeting notes from Thursday June 27 2024:
- Rahim: this issue around “undefined”, and how it is specified, came about as part of WPT aria-hidden test (https://github.com/web-platform-tests/wpt/pull/45694)
- Question: what kind of attributes are ARIA attributes?
- HTML spec describes lots of attributes, e.g., content, boolean, enumerated, etc.
- Valerie: appreciate you doing this work because there are problems with aligning ARIA and HTML because of the IDL part of ARIA. Anne VK. is also working on this
- There may be some information on this in previous IDL discussion
- Mapping is not straight and as clear as it needs to be
- James N.: it depends on the attribute. We have a mapping of the ARIA value types to languages in Appendix A of the ARIA spec. That’s where we have attempted to map this
- James C.: it’s a fairly straightforward answer. Most of them are reflected DOMStrings
- ARIAMixin interface: https://w3c.github.io/aria/#idl-interface
- Most of these have attribute DOMString as the prefix; a few of them are FrozenArray<Element> (anything where we have an object reference to a DOM node or nodes)
- For example, and you can see this by the plurality of the reflected interface, e.g., FrozenArray<Element>? ariaDescribedByElements
- But most are DOMString, so there’s no value type enforced other than string at the IDL layer
- We do have additional prose in spec as to what those values are; part of the reason is because there’s no standard way in IDL to list reflection (implementations differ)
- Rahim: is that why ARIA IDL doesn’t align 1:1 with HTML IDL? ARIA WG seems to approach it differently than how HTML IDL works
- James C.: what we’ve currently always referred to as the ARIA attributes, these are known as content attributes. E.g.,
<someElement attribute=“”>versus DOM properties accessed via JavaScript:element.ariaLabel- HTML is aligning all of their content attributes (which are always string) with the reflected DOM properties which can be of any value type
- There are also rules that determine what happens if the content attribute’s string value doesn’t match one of these data types
- HTML is a little bit more strict and holds off on defining reflections until value type is worked out
- ARIA IDL held off on defining FrozenArray references; part of the reason is that we’ve had ARIA content attributes for a decade or more so there wasn’t a clean transition that wouldn’t negatively affect some web compatibility circumstance (trying to avoid breaking websites by leaving these as DOMString)
- Conversation is not completely closed
- Valerie: linking this issue which has more context: https://github.com/w3c/aria/issues/1110
- James C: to summarize, most of these are DOMStrings and the various stakeholder concluded they will likely stay as such unless there is a very compelling reason to change them now. But there may be other non-string accessors added later, for example CSS added tokenlist classlist to avoid breaking the string classname property. ARIA could do something similar
- Rahim: a couple follow-up questions
- There’s a note in the ARIA spec 6.3.4: https://w3c.github.io/aria/#enumerated-attribute-values-html. Why is this note here?
- If the desire is to align with how enumerated attributes work in HTML, how will the microsyntax for missing value default and invalid value default align with ARIA?
- James C.: ARIA shipped IDL interface in 1.2; at that point, ARIA WG was having open discussions about changing them but it became a self-referential problem
- ARIA WG shipped them as nullable DOMStrings, and not non-nullable DOMString
- The 6.3.4 note may be outdated
- James N.: ARIA spec mentions in 6.3.2 that “missing value default” and “invalid value default” should not reflect to IDL; should use a “null” instead
- Valerie: to Rahim’s question. what becomes null in the IDL interface?
- Rahim: right; what becomes null; for the stuff that gets serialized (i.e., content attributes). Also, does null = undefined?
- James C.: to follow up on James N.’s comment on 6.3.2: part of the reason for that is the problem of unshipping for webcompat reason
- IDL handles some of the base for us, and then provide follow on rules (in spec prose) because we couldn’t write them in IDL and keep backwards-compatible nullable DOMString IDL
- Complicates implementation but priority of constituencies is respected (authors over implementors and spec editors)
- Rahim: if I’m understanding correctly, part of this is also not treating ARIA content attributes as true boolean types (but boolean-like tokens)
- This allows for ability to add new ARIA values to existing attributes
- James C.: when ARIA was first conceived, there weren’t boolean attributes in HTML
- ARIA needed values that could be referenced and later HTML spec solidified these rules formally
- Rahim: what about setting an ARIA attribute to the string value “undefined” vs. non-string value undefined?
- James C.: to some degree, it behaves the same way although not in the IDL
- What we have as aria-hidden is effectively an enumerated attribute
- Look in example 20 in 6.3.4.1 (https://w3c.github.io/aria/#enumeration-example); boolean “false” is effectively missing value default
- However, not reflected this was in IDL because it could break older websites
- Sarah H.: might be my fault for the confusion around quotations or not for “undefined”; my comment differentiated between 1) setting undefined as string in HTML vs 2) IDL attribute and 3)
setAttribute()method- When I put undefined without quotations, was indicating setting it via
element.ariaChecked=undefined, orelement.setAttribute(“aria-checked”, undefined) - In HTML you can omit quotes and functionally the same thing as putting quotes around it
- When I put undefined without quotations, was indicating setting it via
- James C.: but the implementation of that is that it becomes an invalid value default, which is null?
- Sarah H.: I don’t think so; I made a test case (https://github.com/w3c/aria/issues/2177)
- You can pass in undefined without strings and IDL reflection is the string “undefined” instead of null
- James C.: is that the case for all browsers? This is complicated because there is no way (in WPT) to check in-browser representation of the value before it reaches platform API
- Sarah H.: I checked several browsers including Chrome, Edge and Safari
- James C.: although the value itself may be reflected as the DOMString (IDL reflects DOMString “undefined”), implementations may not be up-to-date with ARIA spec
- Also may not be a way to test WPT reflected value
- Sarah H.: to make sure we’re on the same page, this is the difference between
<button aria-expanded=undefined>vs.<button aria-expanded=“undefined”>as there should be no difference in those values - James C.: agreed. What I was trying to understand was effectively, for an enumerated attribute for example, setting undefined (or an incorrect spelling of undefined) reflects the same thing as an invalid value
- Valerie: for the purpose of this discussion and ARIA specification going forward, it might be clear to use these concepts of missing/invalid value default as it’s helpful for more alignment between ARIA/HTML
- Rahim: one thing I would mention is that in HTML, there’s not always going to be a missing/invalid value default so some attributes would return no state (returns nothing as the value)
- Valerie: ARIA WG needs to be clear in spec if an invalid value is treated the same as an undefined value
- Rahim: that’s one of my questions today
- James C.: that’s what is handled by the IDL in HTML for enumerated attributes
- Valerie: because the invalid value is turned into the undefined value
- James C.: correct; ARIA also has a couple of attributes where the invalid value is (if unrecognized) counted as true but there wasn’t a reflection problem in the DOM because it needed to be passed downstream through an accessibility API
- Scott: I wanted to chime in on expectation for undefined value, and we brought this up at a previous ARIA meeting
- In past testing, undefined wasn’t an empty string or invalid value. It seemed to be a way to prime browsers to expect a state change
- For example,
<button aria-expanded=“undefined”>because the button needed a start state but upon pressing, it became a true or false expanded button. However, if I started with<button aria-expanded=“foo”>, then thearia-expandedstate would not be consistently or properly announced - From what I understand, there was a difference between undefined representing an invalid value vs. undefined being a “special”, new value
- James C.: does this count as spec working around a browser bug?
- Scott: is it a browser bug, or is it the fact that there are 3 values defined for aria-expanded (true, false, undefined) and the expectation is that these are probably just strings
- I’m not saying we have to maintain this but we need to make incredibly clear in spec that undefined is not meant to be another token value
- Not sure how many people are relying on this as it’s just one example
- Rahim: should “undefined” the string value be a separate value for some ARIA attributes?
- James C.: I recall early discussions (pre-2010), ARIA allows empty strings or the string as a token “undefined” to be the same value for readability, understandability, and some of it for the implementation problem that Scott pointed out
- Sarah: H. is that happening now for any attributes?
- James C.: not until we can test these downstream, such as ARIA-AT
- Sarah H.: not a fan of having undefined the string map to undefined the value
- James C.: in most cases, it doesn’t matter because the undefined will be the missing/invalid value default
- If you write it in the string “undefined”, it would be an invalid token (like a typo for the word undefined, would trigger the functionality of the missing value default which is undefined)
- “Undefined” would not need to be a special case
- Scott: we need to be explicit in spec because while undefined is default for many attributes, some attributes have “none” as default value and undefined isn’t mentioned at all
- James C.: I agree it should be explicit; perhaps there could be a row added to the characteristics table
- Spec currently has values where you bold the default value
- Could have missing default and invalid default defined explicitly as a token or string value (or null or undefined)
- Scott: I’m fine with that; aria-autocomplete is an example where undefined isn’t specified
- Rahim: I like that approach because it gets closer to HTML concept of enumerated attributes. However, what should be done about section 9.2 and the “Fallback values for missing required attributes” table (https://w3c.github.io/aria/#document-handling_author-errors_states-properties)?
- James C.: for this table, it sounds like the 9.2 table could be removed and the table entries would be integrated in each attribute’s characteristics table
- Called out as two separate values: for missing value default, but spec would also need invalid value default
- Scott: aria-checked is an interesting one; the author error table says fallback value is “false” but undefined is default value
- If the attribute isn’t defined at all, then the fallback value is actually false per author error table
- James N.: ARIA WG needs to be careful about moving stuff from author error table to somewhere else
- Whole point is that validators can flag these as errors if author has not defined something
- It should be flagged because it was probably a mistake
- James C.: there wasn’t a way in IDL to have a role-specific value default that was different from the attribute’s value default
- For example,
aria-orientationdefaults to vertical for scrollbar but default be different for another role
- For example,
- Rahim: what are all the ways to define undefined for HTML (content attributes)? is “undefined” the string OK as an assignment method?
- Valerie: are you referring to everything that is treated as the undefined state?
- James C.: yes, changing it could be complicated
- One place it could be a problem is, for an attribute that had an undefined value, where missing value default and undefined value default should be different
- This would be problematic for this example because if undefined was treated as an invalid value, and resolved different for an undefined value, those two rules would conflict
- Sarah H.: are you saying undefined the string is OK, in a way that is different than keyboard mashing?
- James C.: I don’t know if it’s different in implementations today but ideally, spec would define missing/invalid value default are equivalent to undefined state, they would behave the same way (i.e., undefined string and button masher string would be equivalent and would resolve to undefined state)
- Next steps for ARIA WG
- (From Rahim) close aria #2156/#2177 related to undefined
- (From James) investigate removal of note 6.3.4: https://w3c.github.io/aria/#enumerated-attribute-values-html)
- (From Valerie) determine if an invalid value is treated the same thing as an undefined value
- (From Scott) clarify in spec that undefined is not some starting state to prime browsers for a downstream attribute value change
- (From James/Scott) add missing/invalid value default in characteristics table for each attribute. The spec could have missing default and invalid default defined explicitly as a token or string value (or null or undefined)
Capturing my notes from an IDL meeting with @rahimabdi and @annevk a few weeks ago.
- reflected nullable
DOMString?is unlikely to change, especially now that Gecko shipped it too. - however, it’s possible ARIA WG could update some of the attributes to be defined as proper Enumerated Attributes with enforced values. This would have some validation benefits, would be backwards compatible in all non-author-error scenarios, and would be testable with existing WPT DOM tests.
- Some complications might include the boolean-like ENUM value types defined in the spec: true/false, and true/false/undefined. These are achievable, but authors might be confused.
aria-pressedis a good example where there an enumerated true/false/undefined is critical to distinguish toggle buttons from push buttons. - Another oddity is
aria-invalid, where the MISSING VALUE DEFAULT would beundefined, but the INVALID VALUE DEFAULT would betrue. Other enumerated values includegrammar,spelling, etc… So a misspelledgrammer[sic] would still equate totrue.
The ARIA spec is not in line with the algorithm defined below this portion of the HTML spec: search for “If a reflected IDL attribute has the type DOMString?:” (in particular, ARIA has nullable (?) strings that are not enumerated.)
For web compatibility reasons, implementations would never be able to retrofit the numeric strings to number types, but if needed in the future, we could add another accessor, as was done with CSS element.classList vs element.classname
ARIA WG could consider not adding new DOMString? reflection for non-string types (like numbers) when new corresponding content attributes are added in the future, though this may be confusing to authors unless some convention makes it clear which are strings vs other types. (e.g. as we did with element.ariaLabelledByElements)
Another complication that I forgot to discuss during that meeting is that, without the nullable ? char, all numeric values would have to have defaults… Some would be doable, like aria-min and aria-max could be 0 and 1 like html min and max on <input type=range>, but that would not work for an indeterminate progressbar for example. So there were a number of reasons why these stayed as nullable DOMStrings… It wasn’t just an editorial screw up.
ARIA WG should consider adding notes in the spec (or in a wiki) documenting why these decisions were made.
Adding Agenda+ to discuss potential actions at an upcoming WG meeting. In particular, do we want to track issues for:
- Should we test the DOM to enforce values on the ENUM types defined as nullable DOMStrings? (Plenty of upsides. Are there any downsides besides the inevitable risk of implementation churn?)
- Should the spec document why some of these IDL decisions were made in the past?
- What about the suggestion to not add any new DOMString accessors for non-string types?
- Is there a need for DOMTokenList-like accessors like the CSS WG added for
element.classList? For exampleelement.ariaInvalidList?
Discussed briefly in Aug 9th ARIA WG meeting: https://www.w3.org/2024/08/08-aria-minutes#t08