Open peterkuma opened 10 years ago
Finding the first focuable element seems far too complicated to get right (see HTML Standard: 8 User interaction, so I produced a patch which just sets focus to mfp.wrap when wrapping tab navigation, and as a fall back when mfp.st.focus is not set or does not exist. This fixes both of the problems mentioned, but does not follow the ARIA guidelines.
With ChromeVox, the browser just reads the entire content of the popup (incl. the close button and arrows) when it is initially loaded. I don't know how bad this is compared to focusing the first focusable element, but I guess at least getting right the tab cycling and tab navigation confinement is an improvement.
When the
focus
setting is set to a selector which does not yield any elements, focus is not set correctly in_setFocus
, and tab navigation is allowed to break out of the popup. This can be seen in the Modal popup example, which currently sets focus to#username
(probably by mistake), which is not present in the dialog._setFocus
should check ifmfp.content.find(mfp.st.focus)
is not empty and only then set focus (fall back to mfp.wrap otherwise).If
focus
settting is present, calling_setFocus
from_onFocusIn
in order to contain focus within the popup prevents elements occuring before thefocus
element from being accessible by Tab. This is because when focus is removed from the last element of the popup (and to be moved to a page element), the_onFocusIn
method gives focus to thefocus
element, instead of the first tab-focusable (tabbable) element of the popup. In practice, this prevents the Close button from being accessible by Tab when thefocus
setting is used.There is also a question whether focus should ever be given to mfp.wrap as a fallback. I think it is better to give focus to the first focusable element in the popup. Esp. from WAI-ARIA 1.0 Authoring Practices:
When the dialog box is opened, focus should be set to the first tab focusable element within the dialog. If there is no tab focusable element within the dialog box contents, set the focus to the item that is used to cancel or close the dialog.
Finding the first tabbable or focusable element is a bit problematic (see this stackoverflow question). jQuery UI provides
:tabbable
and:focusable
selectors which are supposed to do that, but they are not available to Magnific-Popup. There is a jquerry.tabbale package which should be able to do that, but I'm not sure Magnific-Popup would want to have such a dependency. There is also the possibility to integrate the code from jQuery UI or jQuery.tabbable, but it is mildly complicated. One can also come up with a simplified CSS selector to find focusable or tabbable elements with a few lines of code (but without handling some special cases).I can provide a patch implementing the last mentioned solution.