You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
readonly/disabled and form-associated custom elements #257
(For disabled it would make sense to use the https://html.spec.whatwg.org/#concept-fe-disabled concept instead as that's what you'd use on a given element to determine whether it's disabled, not the disabled attribute.)
On one hand, these should be exposed because they have semantic value and we expose them for native controls. This is the direction I'm personally leaning in.
On the other hand, IIUC, there is no default styling for these states visually - the author has to style them - so it could be argued that the author should also be responsible for exposing the correct accessibility semantics (equivalent UX).
@annevk and @jcsteh agree here, form associated custom elements should be able to expose these states, and any other applicable state that a native form control could.
In general I would expect if a custom element is set to a specific role via its ElementInternals, then any allowed states and properties of that role should also then be allowed/exposed for that custom element.
We can either go through each attribute and indicate that, for instance, the required attribute is allowed on form associated custom elements, but excluding roles that do not allow required (should HTML's attributes table also note form associated custom elements for required?). Or write something more global that states that if custom element is set to an explicit role, that the custom element should then allow for any states/properties of that role to be exposed.
Glad to do whichever is more preferable, but I personally think the global statement/guidance would be easier to maintain, as the argument could be made that every custom element that has a defined role should then be listed for every attribute that role should allow for.
e.g. the reversed attribute relates to an ol and an autonomous custom element with a declared list role. Or that the selected attribute relates to an option element or a form associated custom element with a declared role=option.
@annevk well i think that's sort of related to what i'm asking here. File an issue for that attribute specifically, or note that really any/all attributes should mention they are associated with autonomous custom element or form associated custom elements if either of those have a role that exposes them as a native HTML element that supports said attribute.
One important thing to note is that disabled and readonly are different in degree, for form-associated custom elements.
FACEs with the disabled="" attribute receive no user interaction events. Basically, the browser implements all of disabled for you, except for any styling you might want to do.
FACEs with the readonly="" attribute only change their constraint validation behavior. Implementing actual read-onlyness is up to the web developer.
As such tentatively I would recommend that the browser make all disabled FACEs count as disabled for a11y purposes, but that it not do so for readonly FACEs. Instead, authors need to implement readonly a11y semantics as part of implementing readonly user interactions generally. This would best be done via ElementInternals, e.g. internals.ariaReadonly = "true".
This seems more likely to lead to aligning a11y semantics with general UX, which IMO is probably a more important goal than aligning a11y semantics with default styles.
I'm open to being persuaded otherwise, however. E.g. I could see the argument that authors are too likely to forget to set internals.ariaReadonly = "true" while working on making readonly="" work for mouse and keyboard events, and so we should automatically make readonly="" attributes on FACEs cause readonly a11y semantics.
I could see the argument that authors are too likely to forget to set internals.ariaReadonly = "true"
This was exactly what I was going to say. I think the more accessibility can be built-in and provided by default, the better. I can't think of a case where you'd want a FACE be readonly and not also want to expose the readonlyness to AT.
The only risk I see is web developers marking a FACE as readonly but then still making it editable, but this seems less likely.
I can't think of a case where you'd want a FACE be readonly and not also want to expose the readonlyness to AT.
The case I'm imagining is component developers not implementing readonlyness at all, i.e. the control still being editable. That is, the page author has set readonly="" on the component, but the component developer has done nothing in reaction to that.
The question in this thread is about how much the browser should do in reaction to the page author setting readonly="". Should it do not-very-much by default, to align better with what happens if component developers take the default path of doing nothing? Or should it do a good amount by default, in the hopes that component developers properly react to page authors setting readonly=""?
In other words, I think we're balancing two potential harms:
If the browser does nothing (current spec): The harmful scenario is where component developers remember to make their control non-editable in response to page authors setting readonly="", but forget to set internals.ariaReadonly = "true".
If the browser adds ARIA readonly semantics: The harmful scenario is where component developers don't respond to the page author setting readonly="", so their controls are editable, but the browser sets ARIA readonly semantics, thus erroneously communicating to AT users that the controls are readonly.
There are controls (such as a custom toggle switch or button) where the component developer intentionally would ignore the page author setting readonly="", because, like the built-in checkbox/radio/button/range/color inputs, readonly semantics don't apply. It's hard to distinguish such cases from the component developer unintentionally ignoring the page author setting readonly="".
We could add some sort of opt-in as discussed in whatwg/html#5016 (comment) to help with this, but see that thread for some of the blockers there.
Thanks, @domenic. As it often the case, things are more complicated.
If there's an opt-in for the :readonly pseudo-class, that seems like an indication that the component developer intends for the FACE to support readonly, so in that case I think it's better to expose the a11y state automatically.
I'm also curious how ATs react to aria-readonly="true". Based on a quick test, it appears that macOS/Safari/VO ignores it, but honors the readonly attribute for input type=text: it omits "To enter text in this field, type." when readonly is present. What do other ATs do?
I'm also curious how ATs react to aria-readonly="true".
NVDA ignores it on all roles except textbox and checkbox. I'm actually not sure why this applies to checkbox. Note that this isn't web specific code - it applies to those roles in native apps as well - so it was probably done for some desktop use case rather than web.
Activity
annevk commentedon Oct 17, 2019
(For disabled it would make sense to use the https://html.spec.whatwg.org/#concept-fe-disabled concept instead as that's what you'd use on a given element to determine whether it's disabled, not the
disabledattribute.)zcorpan commentedon Oct 17, 2019
The thing about disabled appears to be a bug in html-aam for built-in form controls.
https://w3c.github.io/html-aam/#att-disabled
jcsteh commentedon Oct 17, 2019
On one hand, these should be exposed because they have semantic value and we expose them for native controls. This is the direction I'm personally leaning in.
On the other hand, IIUC, there is no default styling for these states visually - the author has to style them - so it could be argued that the author should also be responsible for exposing the correct accessibility semantics (equivalent UX).
annevk commentedon Oct 18, 2019
If we want to go down that route, HTML would need to expose disabled and disabled for form-associated custom elements differently.
But note that while they might not have a default style, they do match
:disabledat the moment.jcsteh commentedon Oct 18, 2019
I don't quite follow your meaning here. Can you clarify how it would need to be exposed differently and why?
annevk commentedon Oct 18, 2019
Because html-aam would need to map one of them and not the other.
jcsteh commentedon Oct 18, 2019
Oh, you mean if we chose to not expose this for CustomElements.
Note that I personally tend to think we should expose it for CustomElements. I was just presenting the other side of the argument as well for balance.
scottaohara commentedon Oct 18, 2019
@annevk and @jcsteh agree here, form associated custom elements should be able to expose these states, and any other applicable state that a native form control could.
In general I would expect if a custom element is set to a specific role via its ElementInternals, then any allowed states and properties of that role should also then be allowed/exposed for that custom element.
We can either go through each attribute and indicate that, for instance, the
requiredattribute is allowed on form associated custom elements, but excluding roles that do not allowrequired(should HTML's attributes table also note form associated custom elements forrequired?). Or write something more global that states that if custom element is set to an explicit role, that the custom element should then allow for any states/properties of that role to be exposed.Glad to do whichever is more preferable, but I personally think the global statement/guidance would be easier to maintain, as the argument could be made that every custom element that has a defined role should then be listed for every attribute that role should allow for.
e.g. the
reversedattribute relates to anoland an autonomous custom element with a declaredlistrole. Or that theselectedattribute relates to anoptionelement or a form associated custom element with a declaredrole=option.annevk commentedon Oct 18, 2019
Yeah, we have it for
readonly. File an issue?scottaohara commentedon Oct 18, 2019
@annevk well i think that's sort of related to what i'm asking here. File an issue for that attribute specifically, or note that really any/all attributes should mention they are associated with autonomous custom element or form associated custom elements if either of those have a role that exposes them as a native HTML element that supports said attribute.
domenic commentedon Oct 19, 2019
One important thing to note is that
disabledandreadonlyare different in degree, for form-associated custom elements.disabled=""attribute receive no user interaction events. Basically, the browser implements all ofdisabledfor you, except for any styling you might want to do.readonly=""attribute only change their constraint validation behavior. Implementing actual read-onlyness is up to the web developer.As such tentatively I would recommend that the browser make all disabled FACEs count as disabled for a11y purposes, but that it not do so for readonly FACEs. Instead, authors need to implement readonly a11y semantics as part of implementing readonly user interactions generally. This would best be done via
ElementInternals, e.g.internals.ariaReadonly = "true".This seems more likely to lead to aligning a11y semantics with general UX, which IMO is probably a more important goal than aligning a11y semantics with default styles.
I'm open to being persuaded otherwise, however. E.g. I could see the argument that authors are too likely to forget to set
internals.ariaReadonly = "true"while working on makingreadonly=""work for mouse and keyboard events, and so we should automatically makereadonly=""attributes on FACEs cause readonly a11y semantics.annevk commentedon Oct 21, 2019
I suspect
disabledmight also require custom logic in a FACE, in particular if it uses a shadow tree and has subcontrols there.zcorpan commentedon Oct 23, 2019
This was exactly what I was going to say. I think the more accessibility can be built-in and provided by default, the better. I can't think of a case where you'd want a FACE be
readonlyand not also want to expose the readonlyness to AT.The only risk I see is web developers marking a FACE as
readonlybut then still making it editable, but this seems less likely.domenic commentedon Oct 23, 2019
The case I'm imagining is component developers not implementing readonlyness at all, i.e. the control still being editable. That is, the page author has set
readonly=""on the component, but the component developer has done nothing in reaction to that.The question in this thread is about how much the browser should do in reaction to the page author setting
readonly="". Should it do not-very-much by default, to align better with what happens if component developers take the default path of doing nothing? Or should it do a good amount by default, in the hopes that component developers properly react to page authors settingreadonly=""?In other words, I think we're balancing two potential harms:
readonly="", but forget to setinternals.ariaReadonly = "true".readonly="", so their controls are editable, but the browser sets ARIA readonly semantics, thus erroneously communicating to AT users that the controls are readonly.domenic commentedon Oct 23, 2019
Another consideration:
There are controls (such as a custom toggle switch or button) where the component developer intentionally would ignore the page author setting
readonly="", because, like the built-in checkbox/radio/button/range/color inputs, readonly semantics don't apply. It's hard to distinguish such cases from the component developer unintentionally ignoring the page author settingreadonly="".We could add some sort of opt-in as discussed in whatwg/html#5016 (comment) to help with this, but see that thread for some of the blockers there.
zcorpan commentedon Oct 23, 2019
Thanks, @domenic. As it often the case, things are more complicated.
If there's an opt-in for the
:readonlypseudo-class, that seems like an indication that the component developer intends for the FACE to support readonly, so in that case I think it's better to expose the a11y state automatically.I'm also curious how ATs react to
aria-readonly="true". Based on a quick test, it appears that macOS/Safari/VO ignores it, but honors thereadonlyattribute forinput type=text: it omits "To enter text in this field, type." whenreadonlyis present. What do other ATs do?jcsteh commentedon Oct 23, 2019
NVDA ignores it on all roles except textbox and checkbox. I'm actually not sure why this applies to checkbox. Note that this isn't web specific code - it applies to those roles in native apps as well - so it was probably done for some desktop use case rather than web.