-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Modal: remove a redundant tab stop on the modal content wrapper #11631
Comments
I checked how Dialog works in
In general, the first focusable element always becomes focused even if this is the close button. Reach UI provides a way to codify which elements gets focused instead with Now the question is whether we keep the default behavior to move the focus to the first focusable element even when it's an diff --git a/packages/components/src/modal/index.js b/packages/components/src/modal/index.js
index f4a64c289..28bfbbb7c 100644
--- a/packages/components/src/modal/index.js
+++ b/packages/components/src/modal/index.js
@@ -134,7 +134,7 @@ class Modal extends Component {
} }
{ ...otherProps }
>
- <div className={ 'components-modal__content' } tabIndex="0">
+ <div className={ 'components-modal__content' }>
<ModalHeader
closeLabel={ closeButtonLabel }
headingId={ headingId } The alternative would be to try to be more opinionated and do some sort of machinery which puts The third option is to keep the default behavior but allow to declare a prop that helps to define a different HTML element to get focused on the initial load, in a similar fashion to Reach UI. @afercia, @enriquesanchez, @tellthemachines and @diegohaz - do you have some other ideas? Side note: I removed |
It's a bit more complicated than this 🙂 In short: the ARIA dialog pattern assumes there are interactive UI controls within the dialog. That's because it's inspired by the operating systems dialogs where at the very least there's a button. The A quick example of a native operating system dialog: In this case, if we wanted to reproduce this in HTML, then the element with
This is because by default, in "forms mode", only the element with role=dialog and form controls are announced. Any other text content is ignored. There are ongoing discussions in the accessibility field because it's clear the ARIA dialog pattern (whether it's modal or non-modal) doesn't fit with the actual usage on the Web. Today, dialogs are used for any kind of content. Potentially also for content that doesn't have any interactive control and it's just text with only a "Close" button. The point is we can't predict what kind of content will be passed to the dialog: it could be anything. Why initial focus matters
Thus it's a "silent" tab stop, as outlined above. And it also doesn't guarantee screen readers switch to the expected mode. I had to face the same issue for the core Media modal dialog where I opted to not follow the recommended ARIA pattern. See https://core.trac.wordpress.org/changeset/45572 Given the Media modal dialog content greatly varies and we can't predict what the content will be (considering also plugin may pass any content) initial focus goes to the element with role=dialog. After that, tabbing cycles only through the tabbables within the modal, at least when tabbing forwards. It's not perfect and technically doesn't fully follow the ARIA pattern but I do think it's the best option. Worth also noting that the content area switches back to In order of preference, I'd like to recommend to:
|
Could we:
I'm suggesting this as a workaround to avoid having the close button as the first thing announced when entering a modal. Though it's fairly standard practice, it still feels a bit off.
My concern here is the more customisation we allow, the greater the chances of accidentally stuffing things up. If we don't want to go the wrapper-first route I described above, then, assuming that there always will be a close button (which there absolutely should be), and that it is always the first focusable element (which we can ensure by making it part of the modal boilerplate), it's best for consistency and predictability that we stick with focusing it first. |
That wouldn't solve the issue that focus lands on an element that has no ARIA role and no semantics.
I think this already works 🙂
This was my request as well at the time when this component was implemented. I'd prefer the title to be enforced and made required through code. As of now, it's only specified as required in the documentation:
I'd agree this component shouldn't allow more customization: it's already complicated in terms of expected interaction and semantics. Allowing more options would open the door to break the expected behavior. Also from a design perspective, I'd tend to think WordPress should provide a consistent look for the modal dialog with a required visible title. |
@afercia and @tellthemachines, thanks for sharing your feedback, much appreciated.
I don't think we can enforce all the things we would love but we need to find a way to make it clear for folks using WP components that they aren't following the best practices. I'm inclined to adopt |
This triggers the error with the latest version of In #18205, I'm going to remove |
Sometimes, some aXe rules are a bit opinionated or don't take into consideration legitimate use cases. Reference: aria-hidden-focus
When the Gutenberg modal dialog opens, it adds The aXe While the general principle of the aXe rule is perfectly fine, I don't think it fits with the ARIA dialog pattern. Tabbing is already constrained within the modal dialog. Which makes impossible to tab to the focusable elements within It would be great to disable this rule only for the modal dialog, and keep it for all the other components, if possible. |
I think we have a similar issue with regions and the way HTML wrappers are organized. Axe has issues processing that :(
I don't know how granular we can go, but I'm sure we can disable checks for the individual HTML elements but I think it also included child nodes. I would have to investigate it one day. |
In 86dad5f#diff-43180d07dbce4319eb9bf0c20e632668R155 a
tabIndex="0"
prop was added to the modal content wrapper, to avoid the close button tooltip to appear on initial focus.While the intent was good, this also made the content wrapper focusable and included in the tab sequence. Now, when navigating with the keyboard through the focusable elements within the modal, there's a tab stop on an unlabelled element.
Screen reader users will get the tab stop but nothing will be announced.
Worth noting this wrapper needs to stay unlabelled. For better accessibility, the best option is to just remove the
tabIndex="0"
and explore a new solution for the tooltip.The text was updated successfully, but these errors were encountered: