question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

manage focus, and use aria-live to announce navigation

See original GitHub issue

https://github.com/sveltejs/sapper/issues/1083, basically.

There are two separate issues to consider in order to make client-side routing accessible:

1. Managing focus

In a server-rendered app, any time you navigate to a page, the <body> is focused. In Sapper and SvelteKit apps, we blur the current activeElement upon navigation, but this doesn’t actually reset the focus, which is what we need — it just removes it temporarily. As soon as you press the tab key (or shift-tab), focus moves to the element after (or before) whichever element was focused prior to the navigation, assuming it still exists in the DOM. This is not desirable.

Went down a bit of a rabbit hole trying to understand current recommendations:

  • Marcy Sutton advises focusing a ‘skip back to navigation’ link (i.e. a skip nav link in reverse)
  • Ryan Florence thinks the app developer should have control over where focus lands, but that it should be an element inside the innermost route that has changed
  • Nick Colley and Daniel Nixon prefer finding some primary focus target, e.g. the <h1>
  • David Luhr suggests resetting focus to the top of the DOM

I’m sure there are other suggestions too. Each comes from an accessibility expert and has a solid argument, but ultimately they are mutually exclusive. Any would be better than the status quo though.

My inclination in the short term is to simply focus <body> (i.e. David Luhr’s suggestion) — it’s easy to implement, and matches the behaviour of server-rendered apps. In the future perhaps we could investigate alternatives, particularly ones that put power in app developers’ hands rather than making one-size-fits-all decisions for them.

The short term solution ought to be fairly straightforward — we just change this…

https://github.com/sveltejs/kit/blob/e09b6be95af81077e0fb0240ad94b1c0e41c9b3a/packages/kit/src/runtime/internal/router/index.js#L180-L182

…to this:

document.body.setAttribute('tabindex', '-1');
document.body.focus();

(Better still, only set the tabindex once, when the router initialises.)

2. Announcing the page change

Per the recommendation in https://www.gatsbyjs.com/blog/2019-07-11-user-testing-accessible-client-routing/, we should add an ARIA live region that announces new pages. That looks something like this:

<div
  id="svelte-announcer"
  class="visually-hidden"
  aria-live="assertive"
  aria-atomic="true"
>Navigated to {title}</div>

This could live inside the auto-generated root.svelte component.

It makes sense for title to simply reflect document.title, I think, rather than introducing some complicated way to customise it, since a page already needs an informational document title for SEO and accessibility purposes.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:11 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
dummdidummcommented, Jan 7, 2021

For future consideration (haven’t really thought this through): Could this be a component that can be imported via $app/a11y or something? People could then use it in their layout like this:

<script>
   import Announcer from "...";
</script>

<Announcer let:title>
   Hey, I've navigated to {title}
</Announcer>
0reactions
Badlapjecommented, Feb 14, 2022

As an added suggestion: can we add an a11y tag to the issue tags? I’d be happy to help out where i can with anything a11y related. It’s easier to search for those issues if there’s a tag for it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

ARIA live regions - Accessibility - MDN Web Docs - Mozilla
ARIA live regions fill this gap and provide a way to programmatically expose dynamic content changes in a way that can be announced...
Read more >
Focus Order and Managing Focus on Websites
An aria-live region will announce changing items on the screen without rerouting focus to the element when set to polite. For example, a...
Read more >
Provide notification of dynamic changes to content
Use the aria-live attribute on the container of the content that may be ... Change focus only when an alert is critical to...
Read more >
DEV 8.2 – Use ARIA to announce updates and messaging
Using aria-live ="polite" queues the announcement until after the current ... an announcement should be made to the user without them having to...
Read more >
Web Accessibility: Aria, Focus, Focus Management - Telerik
The way focus rings know how to navigate the tab order is by using what is called the tab index of elements. Naturally,...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found