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

[NEXT-1178] Remove focus from next/link element after page change #33060

Open
AshConnolly opened this issue Jan 6, 2022 · 4 comments
Open

[NEXT-1178] Remove focus from next/link element after page change #33060

AshConnolly opened this issue Jan 6, 2022 · 4 comments
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.

Comments

@AshConnolly
Copy link

AshConnolly commented Jan 6, 2022

Run next info (available from version 12.0.8 and up)

No response

What version of Next.js are you using?

12

What version of Node.js are you using?

14

What browser are you using?

Chrome, Firefox

What operating system are you using?

macOS

How are you deploying your application?

other

Describe the Bug

In Chrome & Firefox, when changing pages using a next/link the clicked anchor remains focused after page change. This causes anchor styles to remain in their focused state.

I found this issue - #2768 from a few years ago that solved this problem.
This is the PR created by @connor-baer for that issue - #3545. The solution was to do document.body.focus() on every route change.

However, the issue appears to be back.

giiif

Expected Behavior

When changing pages with a next/link the clicked link should no longer have focus after page change.

To Reproduce

Visit this in chrome or firefox and click the header links: https://stackblitz.com/edit/nextjs-js-focus-issue

NEXT-1178

@AshConnolly AshConnolly added the bug Issue was opened via the bug report template. label Jan 6, 2022
@AshConnolly
Copy link
Author

Short term solution in _app.tsx:

  const router = useRouter()

  useEffect(() => {
    document.activeElement instanceof HTMLElement && document.activeElement.blur()
  }, [router])

To my knowledge this should't have any accessibility implications.

@balazsorban44
Copy link
Member

balazsorban44 commented Jan 10, 2022

Hi, so I believe this behavior is the result of research that ended up being implemented in the following PR: #20428

Please have a read at the (quite lengthy) thread there and consider closing this issue if you got your answer. If you are still unsure, let me know and I'll get further assistance on this.

In short, I think the conclusion was that resetting focus to body is not the most desirable.

@LarsEjaas
Copy link

I have read different posts on this and am still unsure of the desired behavior here.

I have an SPA where things like header and footer are persistent across all routes, but if the user e.g. has used the keyboard to select a different page in the footer on a lengthy page, I do not feel it is very user-friendly to be starting with keyboard navigation on the next page from the footer.

Right now I have an effect running after route changes (excluding any changes in query-parameters of course) that will focus the first page element if no modals are open. But I am unsure if this is good practice in terms of accessebility.

@khinshankhan
Copy link

+1 I currently have this focus and blur:

export function focusSkipNav(blur = false) {
  const el = document.getElementById("skip-nav")
  if (el) {
    el?.focus()
    if (blur) {
      el?.blur()
    }
  }
}

export function yieldSkipNav() {
  focusSkipNav(true)
}

which I run on page change as well

  useEffect(() => {
    router.events.on("routeChangeComplete", yieldSkipNav)
    return () => {
      router.events.off("routeChangeComplete", yieldSkipNav)
    }
  }, [router.events])

it seems to resolve the sticky issue and sets the focus to where I expect it to be, but I'm not clear about accessibility around this either.

I think it's in line with Marcy's comment but it was a little confusing to read

The research of mine that you mentioned recommended that focus should be sent to a small, keyboard-interactive element like a skip link. Sending focus to an h1 or wrapper element works for some aspects, but wasn't really the recommended solution. I also want to make sure visible focus outlines are considered, even if it takes using :focus-visible or something like what-input to keep mouse users happy. There is a lot of value in showing the user's focus point after it moves, and focus outlines are often turned off for wrapper elements (and in general).

and I'm not sure if leaving focus on those elements is good ux since it'll make most skip nav implementations visible on page change.

@timneutkens timneutkens added the linear: next Confirmed issue that is tracked by the Next.js team. label May 17, 2023
@timneutkens timneutkens changed the title Remove focus from next/link element after page change [NEXT-1178] Remove focus from next/link element after page change May 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team.
Projects
None yet
Development

No branches or pull requests

5 participants