web-components
web-components copied to clipboard
Make disabled components focusable and hoverable
What is the problem?
Disabled components currently have tabindex="-1"
, which removes them from the keyboard tab order, making them effectively un-focusable, and, as a side-effect, makes them effectively invisible to assistive technologies, thus bad for accessibility.
The disabled state also applies the pointer-events:none
css property, which disables hover/mouseover based functionality such as tooltips. This is unfortunate especially as tooltips are a convenient way to inform the user why a component (e.g. a Button) is disabled. Removing this would require some additional css and js to handle the pointer-inertness of the component, but enabled tooltip usage.
Ideally this behavior would be configurable via a feature flag or a global property, so that applications for which it is desired to keep the current behavior could easily revert back to it.
Browsers
- [X] Chrome
- [X] Firefox
- [X] Safari
- [X] Safari on iOS
- [X] Edge
Screen Readers
- [ ] None
- [X] NVDA
- [X] JAWS
- [X] VoiceOver on MacOS
- [X] VoiceOver on iOS
aria-disabled='true'
could still be applied, which could be used as styling attribute and helps sreenreaders to know that this button is disabled. See e.g. Aria-disabled or How can I make a disabled button focusable, clickable, in general “interact-able”?
Actually, unless I'm mistaken, we don't even have to remove the disabled
attribute on the root element, as that has no effect on custom elements.
Yes, we still need to keep disabled
for styling and to ensure that e.g. setDisableOnClick(true)
works as expected.
Also, we need to ensure that click
events would not fire on disabled elements (maybe stop propagation for them).
This issue would also be relevant for vaadin-tooltip
as users might want to use it with disabled components:
- https://github.com/vaadin/flow-components/issues/4393
- https://github.com/vaadin/flow-components/issues/4455
The current workaround would be to wrap disabled component in a different element and set a tooltip for it.
Just noting, that e.g. with buttons, it is possible to override the style using this in styles.css
vaadin-button[disabled] {
pointer-events: auto;
}
it is possible to override the style using this in
styles.css
An unwanted side-effect of that is that disabled button will then apply :hover
and [active]
styles, making them appear clickable.
Just noting, that e.g. with buttons, it is possible to override the style using this in styles.css
Horrible UX (open/close flicker) with Select as well, so not a generically viable solution.
Having said that. @TatuLund 's idea seems to work really well for one customer of mine. They claim they have tested a huge range of components with the events enabled along the implementation above. Only Select, for them, exposed an unwanted flicker. Maybe an implementation with pointer events being enabled is not as hard as we think (bar the testing).