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

Consider defocussing the page after page change #87

Closed
Wolfr opened this issue Jan 31, 2020 · 13 comments
Closed

Consider defocussing the page after page change #87

Wolfr opened this issue Jan 31, 2020 · 13 comments
Labels
enhancement New feature or request

Comments

@Wolfr
Copy link
Collaborator

Wolfr commented Jan 31, 2020

We should consider defocussing the page on page change.

Otherwise a screen reader user has no idea that they are on a new page.

Reference: https://github.com/oaf-project/oaf-svelte-routing

@jakobrosenberg
Copy link
Member

Agree. As long as we allow for exceptions, like we do with scroll resets and scroll-lock.

@jakobrosenberg jakobrosenberg added the enhancement New feature or request label Feb 2, 2020
@Wolfr
Copy link
Collaborator Author

Wolfr commented Feb 25, 2020

Since accessibility is important to us, we have been doing some tests regarding this, making an example of how a regular HTML page reacts to a page changes as opposed to an SPA.

Now, what is the difference between this? The problem is that with the Svelte version, the user of a screen reader does not know that they are on a new page. There is no defocussing (Related #87), no jumping to top.

Gatsby has recently come up with a solution for this. They solve this in two ways, one by adding a skip link, and one by announcing a new page using an aria live region. The skip link is a decision of the site author to add, we cannot enforce that from the router.

The announcing of a page could be good, but I am not sure if screen reader users really appreciate that - this is something I want to investigate further.

Gatbsy has a writeup on their recent solution here. It comes with its own localization problems.

This is all fairly new territory; the blog posted is from 2 weeks ago. I will be consulting with a local accessiblity expert, and checking more things in depth.

Special mention for Emily in our team for her investigation.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Feb 27, 2020

It's quite clear how if you walk through a regular site, with focus styling on the nav elements, that it needs defocus. For those interested this is also a preview of what we're working on re: the website.

https://routify-2020-khaki.now.sh/

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 10, 2020

I worked a bit on this issue.

This in the script tag of the main_layout.svelte:

import { tick } from 'svelte';

let active = null;

async function update(event) {
    await tick();
    active = document.activeElement;
}

document.addEventListener('focus', update, true)
document.addEventListener('blur', update, true)

And this in the HTML:

{active}

Gives you a hint of what is focussed at the moment.

Now, to defocus it on page change, that is the next step.

There's is a helper beforeUrlChange but is there something like afterPageChange?

@jakobrosenberg
Copy link
Member

There's is a helper beforeUrlChange but is there something like afterPageChange?

No, but we should add one.

I can write a defocuser, but how do we implement it in a scoped fashion? A lot of people, me included, use the URL for state handling and nested views. Imagine a page with two widgets. A ControlWidget and a ViewWidget. The ControlWidget controls what's going on in the ViewWidget and the ViewWidget's state is stored in the current address. In this case defocusing the ControlWidget on URL change might be an unwanted effect.

One way to approach it would be to grab the active element, traverse through its ancestor elements and if no stay-focused attribute/value is found in any of these, then it gets defocused.

This would be similar to the scroll-lock attribute which works in the same manner.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 10, 2020

I noted in my research that Gatsby on their site does not defocus links when changing pages. I wonder if that is considered a bug or intended behavior. I asked the accessibility expert on their team on Twitter but chance might be slim to get an answer.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 10, 2020

If you can see well but you have a motor impairment (or you are just not a mouse user), and rely on keyboard nav the keyboard the persistence of focus is actually very helpful behavior to navigate the website. I.e. try to navigate Twitter.com using keyboard only: it is very well done.

If you can't see and use a tool like Apple's Voiceover to read the screen, you encounter 2 behaviors;

  1. sites that are server rendered which always put but you back at the top of the site when changing pages
  2. Sites that act as an SPA (hydrated SSR or SPA) where a link will keep focussed if it exists on the next page, but the page will defocus as a whole if the link does not exist on the next page

I wonder how people with visual impairments figure out where they are if the behavior is not consistent. Now, visual impairment is a spectrum as well. So a lot of this is probably about user expectation.

I should make a video of me navigating through a site with a screen reader to give you an idea of what I am talking about.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 10, 2020

Update, after some more reading, still convinced that initial problem is correct, with some added info: it would be best to focus the skip link (see info here).

However, this focusses the skip link for everyone, which then causes a problem for people who do not use the keyboard (Vue.js demo at https://ns7t5.csb.app/ - try clicking to a new route). I find this permanence of an unknown UI element unacceptable for the users who do not need it.

I would propose to simply start over again at the top of the body.

The idea of the scoped solution sounds bery good @jakobrosenberg - just want to avoid once again to implement things few people will understand - but then we are back at the discussion we recently had with being able to opt out of behavior with flags vs simplicity of the engineering solution.

The problem as well is that the skip link is a decision in userland. We can't ship a skip link with our router (well, we could techically do it if we provide a default template in Routify-starter)

@jakobrosenberg
Copy link
Member

I did a google to see what solutions others had come up with.

This one was the bulk of the work. When an area of a page or the full page changes, we have to communicate this change to screen readers so they can keep users in the know. It’s frustrating that browsers and screen readers do not work consistently with each other (i.e you will have something working on VoiceOver and Safari that does not work on NVDA and Firefox). The most reliable way I found to overcome this challenge was to set the focus on the heading of the area that’s changing. If you are routing to a new page, I would set the focus to the heading of that page (typically h1). If the update is a dialog box that shows without routing, then I would set the focus on the heading of the dialog box window (typically h2). This will ensure that the screen reader announces the changes. This method worked on Jaws, NVDA and VoiceOver.

https://medium.com/@aziz.marwan/accessibility-considerations-when-building-single-page-applications-53c625e1dc87

There are different strategies as to what to read out on a route. In an SPA, you could choose to set focus to the top of the document when you do a route, this would make it feel like a multi page application. Users would have to use skip links to get back to the content, just like in multi page applications. But maybe you only update one section, and your strategy is to move focus to the new content. In this case, you could ensure the title of whatever is new is read out, rather than the updated page title. For example, if you replace the main by something new and then focus the new content, convey to assistive technologies what the title of the newly focused content is, for example by having its first heading announced.

https://hiddedevries.nl/en/blog/2018-07-19-accessible-page-titles-in-a-single-page-app

Make sure that client-side view changes are known to screen reader users by announcing the change in page title, using ARIA live regions and/or focus management.

https://www.deque.com/blog/accessibility-tips-in-single-page-applications/

I wonder if it wouldn't be better to move focus to the new page/content rather than defocusing.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 13, 2020

By simply adding this code in, I had a working page announcer.

<div id="svelte-announcer" class="u-hide-accessibility" aria-live="assertive" aria-atomic="true">Navigated to: {pageTitle}</div>
.u-hide-accessibility {
  position: absolute;
  left: -10000px;
  top: auto;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

This depended on a variable with the page title being available. This might tie into your recent work with the meta things @jakobrosenberg .

@jakobrosenberg
Copy link
Member

Well, there is a focus thing now, which should be available in the next release.

It just occurred to me that decorators also could alleviate the whole focus situation.

@jakobrosenberg
Copy link
Member

This should be fixed. If not, we'll reopen.

@Wolfr
Copy link
Collaborator Author

Wolfr commented Mar 28, 2020

Yess the defocussing is working on https://routify.dev/ :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants