This content originally appeared on Hugo “Kitty” Giraudel and was authored by Hugo “Kitty” Giraudel
Single-page applications (SPA for short) have been all the hype for the last decade or so. The idea is that we can avoid reloading the entire page when navigating within a site and instead update only the moving parts (usually the content area). This comes from a great premise: faster interactions, no unnecessary HTTP roundtrips, less used bandwidth.
The thing we usually don’t think about is that many assistive technologies such as screen-readers have been initially authored with the “original web” in mind and rely on page (re)loads to announce the page context, namely the page title (hold by the
element).
When building a SPA—no matter the framework—it is important to do some work to announce the title when following router links. Two things need to happen:
- The title of the new view/page needs to be announced.
- The focus needs to be preserved or moved to a proper place.
A nice solution is to have a visually hidden element at the top of the page which receives the new title when navigating, and move the focus on that element so the content is read. Ideally, the skip link lives right after that node so the flow goes like this:
- Press a link in the content area that causes a router change.
- The view gets loaded.
- The title for that view gets rendered in the invisible node.
- The focus gets move to that node so its content is announced.
- Tabbing once gets to the skip link, so getting back to the content area is fast and convenient.
Here is how our HTML should look like:
<body>
<p tabindex="-1" class="sr-only">…p>
<a href="#main" class="sr-only sr-only--focusable">Skip to contenta>
body>
And our unflavoured JavaScript. Note that this is no specific framework—it’s just a made-up API to illustrate the concept.
const titleHandler = document.querySelector('body > p')
router.on('page:change', ({ title }) => {
// Render the title of the new page in the
titleHandler.innerText = title
// Focus it—note that it *needs* `tabindex="-1"` to be focusable!
titleHandler.focus()
})
You can find a more in-depth tutorial for React with react-router
and react-helmet
on this blog. The core concept should be the same no matter the framework.
Note that if you have can guarantee there is always a relevant element (independently of loading states, query errors and such), another possibly simpler solution would be to skip that hidden element altogether, and focus the
element instead (still with
tabindex="-1"
).
This content originally appeared on Hugo “Kitty” Giraudel and was authored by Hugo “Kitty” Giraudel
Hugo “Kitty” Giraudel | Sciencx (2020-12-07T00:00:00+00:00) A11yAdvent Day 7: Page Title in SPA. Retrieved from https://www.scien.cx/2020/12/07/a11yadvent-day-7-page-title-in-spa/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.