Skip to content
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

Mobile navigation focus issue #787

Merged
merged 8 commits into from
Nov 3, 2021
Merged

Mobile navigation focus issue #787

merged 8 commits into from
Nov 3, 2021

Conversation

ludoboludo
Copy link
Contributor

Why are these changes introduced?

Fixes #76

What approach did you take?

The code in placed looked good. What I found is that the issue was related to the transition of the submenu appearing. So I had to move the trapFocus() into a setTimeout() function as well.

It seemed to work with 50ms but I used 100ms as I thought it gave us a safe gap. I tried with no value mentioned but it wasn't working sill. I tried on slow 3g and it worked fine.

Other considerations

Open to other suggestions.

Demo links

Checklist

@ludoboludo ludoboludo requested a review from svinkle October 18, 2021 19:24
@ludoboludo
Copy link
Contributor Author

Another issue I noticed though while looking into this one is the fact that focus isn't trapped properly in submenus: video

The first part is fine, it's trapped properly but submenu isn't working as it should I believe.

@svinkle
Copy link
Member

svinkle commented Oct 18, 2021

focus isn't trapped properly in submenus

So this one's interesting. Since the navigation is functionally implemented as a disclosure pattern (and not a modal dialog pattern), trapping keyboard focus is not required.

However, since we visually hide content by pushing the submenu content "over top" of the parent content, items "below" should not be focusable. Details in #769.

@tyleralsbury
Copy link
Contributor

If the issue is the transition's timing, did you try using the transitionend event?

https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/transitionend_event

tyleralsbury
tyleralsbury previously approved these changes Oct 19, 2021
tyleralsbury
tyleralsbury previously approved these changes Oct 19, 2021
@svinkle
Copy link
Member

svinkle commented Oct 19, 2021

It seems to work some of the time. How can we avoid using timers? Also per my comment above, trapping focus is not required here, if that helps at all.

@ludoboludo
Copy link
Contributor Author

It seems to work some of the time. How can we avoid using timers? Also per my comment above, trapping focus is not required here, if that helps at all.

With the latest change it's not using a timer but a transitionend event listener. So it waits for the drawer of the submenu to slide in then applies the focus to the right element.

When I tested it worked every time (chrome on my laptop and on my android device), when did it fail for you @svinkle ?

@svinkle
Copy link
Member

svinkle commented Oct 19, 2021

when did it fail for you

Just tried the linked demo store when I made the above comment.

  1. Tab to nav control
  2. Space to open
  3. Tab to subnav control
  4. Space to open – works well so far
  5. Esc to try again
  6. Repeat 2-4, no visual indicator or focus management.

@@ -18,6 +18,7 @@ document.querySelectorAll('[id^="Details-"] summary').forEach((summary) => {
event.currentTarget.setAttribute('aria-expanded', !event.currentTarget.closest('details').hasAttribute('open'));
});

if (summary.closest('header-drawer')) return;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm adding a check here so it doesn't add the event listener on the summary elements from the menu drawer. As it has it's own behaviour that is tackled in the class declaration (onKeyUp(event)).

But is it good idea to add a check for a specific element within a function that is general like this one.

I could also remove the IDs on the <details elements from the menu drawer and re add an accessibility function in the menu drawer class that would basically do the same as what's happening in this one.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@tyleralsbury if you have a chance to look at the code again. Curious to hear your thoughts on adding a check here.

@ludoboludo
Copy link
Contributor Author

Should work properly now @svinkle if you want to give it another shot 🙂

@svinkle
Copy link
Member

svinkle commented Oct 21, 2021

@ludoboludo Seems to work well everywhere except Chrome + Talkback. Sometimes it doesn't shift focus as expected. Testing on my Pixel 5, so it shouldn't be "underpowered." 🤔

Video

Notice Talkback green boarder sometimes does not shift in focus as expected.

screen-20211020-153825_2.mp4

@ludoboludo
Copy link
Contributor Author

Hmm yeah from what I notice, talkback doesn't trigger the animation of the next menu happen to appear. And since we're waiting for the transitionend event, then trapFocus() doesn't end up running. I wonder why in VoiceOver it does trigger things properly but not in TalkBack 🤔
I will try and see what I can find.

@ludoboludo
Copy link
Contributor Author

ludoboludo commented Oct 21, 2021

From what I can tell, the issue is that double tapping to open the submenu does, most times, not trigger the transition that we have set in CSS when applying the .menu-opening class. Not sure why 🤔

That made me think that if there isn't a transition, then our transitionend event listener isn't going to work. So I added a check for the prefer-reduce-motion media query. From what I tested on my mac it works well when I check the reduce motion option in the accessibility settings. 👍

assets/global.js Outdated
setTimeout(() => {
detailsElement.classList.add('menu-opening');
!reducedMotion || reducedMotion.matches ? addTrapFocus() : summaryElement.nextElementSibling.addEventListener('transitionend', addTrapFocus);
summaryElement.setAttribute('aria-expanded', true);
});
Copy link
Contributor Author

@ludoboludo ludoboludo Oct 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only thing I found so far is that adding 100ms to this setTimeout() seem to make it work consistently with TalkBack...

Copy link
Contributor Author

@ludoboludo ludoboludo Oct 25, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I check on /main the same issue is happening specifically with TalkBack. The transition isn't always triggered but when you're navigating by touch it's fine. Not sure how else to tackle this one. cc: @svinkle

@svinkle
Copy link
Member

svinkle commented Nov 1, 2021

@ludoboludo Let's get this one merged and revisit if it comes up again during usability testing.

svinkle
svinkle previously approved these changes Nov 1, 2021
@ludoboludo
Copy link
Contributor Author

Should be good for approval and merge now I believe . cc: @tyleralsbury @svinkle

Copy link
Contributor

@tyleralsbury tyleralsbury left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-tested and code looks good.

@ludoboludo ludoboludo merged commit a890eed into main Nov 3, 2021
@ludoboludo ludoboludo deleted the mobile-sub-nav branch November 3, 2021 19:42
phapsidesGT pushed a commit to Gravytrain-UK/gt-shopify-dawn-theme that referenced this pull request Sep 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Header] Mobile sub-navigation control does not manage focus
3 participants