Skip to content

Skip to Content Link is woefully incorrect #3917

@Mythra

Description

@Mythra

🐛 Bug Report

tl;dr skip to content link is not accessible (I am willing to fix, but there are some trickiness as I describe in expected behavior)


Currently Docusaurus sites are rendered with a "Skip to Content" link for accessibility. This was a pleasant surprise to me as quite a few documentation sites with my screen-reader have to go through lots of navigation. Unfortunately, it appears that the Skip to content link currently does not help accessibility, and actually for it's button introduces more accessibility issues.

The guidelines for determining if a Skip to Content link can be found here: https://www.w3.org/TR/WCAG20-TECHS/G1.html. I'll break this down:

  1. Check that a link is the first focusable control on the Web page.

    • Currently the "skip to content" link is a button. While the styling can be made to look like a button (that's more than fine!), it not being a link is problematic as most people (myself included), listen for "link", and if I don't hear that I just start tabbing through before it reads "skip to main content". As it's the "agreed" upon standard.
    • As a side note this button currently only activates if "enter" is pressed. This is problematic as Enter can most often be taken elsewhere. The space bar natively works for button's normally, or synthetically inject clicks. So have onClick/space not work can create a very frustrating experience, and may make it impossible to click.
  2. Check that the description of the link communicates that it links to the main content.

  • This is properly communicated, but as a side note it says "Skip to content links", but only one link is presented. This is a small thing, but really I think we meet this.
  1. Check that the link is either always visible or visible when it has keyboard focus.
  • We meet this 🎉 , no notes needed.
  1. Check that activating the link moves the focus to the main content.
  • This is the big problem. The current skip to content link doesn't actually move focus! This means the screenreader doesn't actually jump anywhere. Meaning all this does is add an extra link for us to jump through. Making it harder to get to the main content. The ways this can happen are:

    • There may be no main id, so it may not even scroll to that element. Making it do nothing.
    • There also are many keycodes/clicks that disable the function working altogether.
    • scrollIntoView() is not the proper way to get the screenreader to stop reading what it is, and instead focus elsewhere. As it is not guaranteed to start reading from that point on. Either focus() should be called explicitly, or we can just link.
  1. Check that after activating the link, the keyboard focus has moved to the main content.
  • Again the focus is not moved to the main content.

Have you read the Contributing Guidelines on issues?

Yes

To Reproduce

Load up a screenreader, I recommend using one of the popular combinations which according to the latest webaim survey is:

  • NVDA + Chrome on Windows
  • VoiceOver + Safari on OSX

Attempt to skip to the main content, and notice the content doesn't actually jump (and reads out as a "button", not link!)

Expected behavior

The skip to main content should always skip to the main content, and is a link. This is actually why I'm filing the issue, as I attempted to just file a PR, but there's a couple bits that make this complex to fix always:

  • We could do the simplest thing and link to a particular ID, Main elements aren't tagged with an ID such as "sr-main". We could add this to all generated templates, but what's the best way to ensure sites already generated have an "sr-main"? Ideally we'd introduce some sort of lint rule, or error case? Unsure what the best way to do that as that.

    • This would be the most common case, and easily support cases where someone didn't use the main element.
  • We could make the content a link, and have a custom onclick handler (not overriding any key caps)

    • This would let us keep the scrolling behavior already introduced, we'd just also have to move focus. The question is what do we do when we can't find a "main" element? Currently this does nothing which is incorrect. A couple IDs I have:
      • We could fall back to some sort of ID, or some sort of other identifier, but again how do we add a lint rule to catch the fallback?
      • We could do some sort of announcement that it failed, but that'd require having a screen-reader announcement div somewhere on the page (this usually is at the bottom of the page), and requires a lot of new behavior. As we'd probably want to expose this to the user so there's not two announcement divs on the page that could be fighting for the screen-reader attention.
      • We could just not render the link, but I don't know a good way of querying if the content has a <main> element during the first render. Maybe there's a simple way, but I don't know it.

Reproducible Demo

Any Docusarus 2.0 site, running a newer version exhibits this behaviour.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAn error in the Docusaurus core causing instability or issues with its execution

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions