fluid-lab / gamepad-navigator

GSoC 2020 project
Other
7 stars 10 forks source link

Add "section" and/or "heading" navigation. #123

Open duhrer opened 10 months ago

duhrer commented 10 months ago

I have been thinking a lot about how this project overlaps with keyboard navigation and screen reading. One idea that screen readers tend to support is navigating "by section".

Although navigation will become less painful once #108 allows the tab navigation controls to repeat, I think it would also be useful to add support for navigating "by section" and/or "by heading".

This would take a lot of the sting out of navigating through long documents or pages (like many Wikipedia articles). It might also make it less urgent to deal with #99. That being said, I suspect we'll end up addressing both at once, as the core idea (move the focus over longer distances) is similar.

Our current "next/previous" item navigation is based on document.activeElement (or the active element in a modal if one is open).

What we want for section navigation (and #99) is:

  1. To scroll the page to the start of a piece of content.
  2. To ensure that forward navigation will focus on the first focusable in the new piece of content.
  3. To ensure that backward navigation will focus on the focusable before the first focusable in the new piece of content (ex: the last focusable in the previous page section).

It would be very helpful to understand how browsers track the fact that I have clicked in a different non-focusable part of the part and decide to tab navigate in that neighbourhood.

duhrer commented 10 months ago

I found a blog that describes exactly what are trying to figure out. Internally, each browser tracks the "sequential focus starting point", which is how it knows to start tabbing near where you clicked your mouse.

Sadly it doesn't seem like there is a good programmatic way to accomplish this at the moment, but there's a proposal to add a method. There seems to be some early work on this against Chromium, but I can't see any evidence of that being available as a flag in Chrome at the moment.

In the mean time, the broad approach to following a section link is:

  1. Detecting that it's a section link, i.e. inspecting all links to see if their start matches the current page.
  2. Add a tabindex of 0 to the destination element if it doesn't have one (or if it's set to -1).
  3. Call the destination element's focus method.
  4. Restore the previous value of tabindex when you can, for example when the element is blurred.
duhrer commented 9 months ago

This works for "jump to content", but could be extended to cover other headings. But first we'd need to see what accessibility tools consider headings/sections, like:

  1. Screen readers
  2. UIO
  3. WCAG

Once we know what a section is, we can either temporarily make the whole section focusable (as we did in #99), or add an invisible focused element at the beginning of the section.

duhrer commented 9 months ago

Looks like UIO looks for an builds its table of contents based on headings.