简体   繁体   中英

NVDA Skips first focusable element on initial page load when tab pressed

Recently while attempting to make my site accessible I stumbled upon a bizarre problem. During the process of setting up a 'skip navigation' link, I noticed that when the page is initially loaded (by 'initially loaded', I mean in a clean browser session, not on refresh—as NVDA keeps a track of the last focused element so results would be dependent on that).

When the page loaded and the tab key pressed, the element that received focus was the 2nd element (which as you will see from the below simplified example, is the site logo/name (also an anchor link)).

The problem doesn't show when NVDA is not running... everything works as expected, Firefox works perfectly fine with or without NVDA running but the problem is present in Chrome, Edge and Opera desktop. I've not tested it on any other browsers thus far.

Please note, because of the nature of the problem, I didn't include a runnable code snippet or fiddle (as there would be other elements on the screen and, as I said this problem only shows with a new browser session/clean page load. Here is some simplified code to show the problem...

CSS

body, html {
  margin: 0;
}

.skip-nav {
  position: absolute;
  margin: 10px 0 0 10px;
  white-space: nowrap;
  display: inline-block;
  padding: 0;
}

.skip-nav a {
  position: absolute;
  left: -1000px;
  border: 2px solid blue;
  border-radius: 2px;
  background-color: black;
  padding: 5px;
}


/* Move link into viewport when focused */
.skip-nav a:focus {
  left: initial;
}

nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 30px;
  background-color: darkblue;
  padding: 10px;
  color: white;
}

nav ul {
  list-style: none;
}

nav li {
  display: inline;
  margin: 0 5px 0 5px;
}

a {
  text-decoration: none;
  color: white;
}

a:hover {
  color: rgb(165, 165, 165);
}

HTML

<!-- Should get focus first, only does in FF when NVDA is running, not in other tested browsers -->
<div class="skip-nav">
  <a href="#main-content">Skip navigation</a>
</div>

<!-- Dummy nav bar -->
<nav>
  <a href="#">Name</a>
  <ul>
    <li><a href="#">Home</a></li>
    <li><a href="#">Services</a></li>
    <li><a href="#">About</a></li>
    <li><a href="#">Contact</a></li>
  </ul>
</nav>
  
<!-- Main site content -->
<section id="main-content">
  Lorem ipsum dolor sit amet consectetur adipisicing elit. Animi dolores voluptates temporibus culpa in quia et magni laborum architecto fugit!
</section>

Things I have tried

The first thing I did was to disable all my browser extensions/test in Chrome incognito mode. Then I tried in the other browsers mentioned above. I also tried other focusable elements (such as a button and even a div with the 'tabindex=0' attribute set. I also put my initial link on its own (not within a parent div). All gave the same results.

Workaround

Instead of placing the link in a div, I put it in an ul/li... and it works perfectly...

<!-- Using a UL works... but not with bullets hidden
<ul class="skip-nav">
  <li>
    <a href="#main-content">Skip navigation</a>
  </li>
</ul>

So I thought I would just set the list with the following property in my CSS...

list-style: none;

The bullet disappears but the problem returns...

For now, I've stuck with the 'fix', but instead of setting the list-style to none I've simply removed the padding from the list so that when it's over to the left side of the screen, the bullet remains off-screen and hidden. I've tested this in all browsers and it works, save for the fact that screen readers still read and announce the 'bullet' when traversing elements (in NVDA, using the arrow keys). Not a massive deal-breaker but this seems a very 'hacky' way of achieving (something close to) the desired result.

Just to summarise, to reproduce the problem the browser must be a new session. With the page loaded, the first tab press should focus the link in the 'skip-nav' div. Currently with the above example the initial tab seems to ignore the first link (unless in a bulleted list). However, shift-tabbing backwards then does focus the link as would be expected.

Is there something I'm missing?

This is a visual focus problem, when you load the page focus is placed on the document (by the browser) and the first link is already focused (by NVDA) if it isn't wrapped in a <ul> . NVDA also doesn't report that the item is focused using NVDA + Tab .

However if you press Space to activate the link you will see it is indeed focused as the URL updates.

My guess is it is something to do with how NVDA places the review cursor when focus changes programatically and how it interacts with the first item on the page.

Also if you put focus into the URL bar after the page loads (resetting the focus) and Tab into the document it behaves as expected.

This appears to be a long standing bug but I couldn't find any answers as to what particular part of the process causes this. It is also a bug I was unaware of until today so I will do some more digging (my sites are affected by this).

The only thing I can think is that the browser focuses the document the first link on the page is the first text and when the review cursor is placed on it it assumes that the link is activated (or focus is set by NVDA before the document is rendered...pure conjecture though).

How to fix for yourself

One way around this is to change your settings in NVDA.

Right click NVDA icon -> Preferences -> Review cursor... -> uncheck "Follow system focus".

At that point you will see that the first item on the page is automatically focused correctly.

查看显示未选中第一个选项的光标窗口(跟随系统焦点)

How to fix for everyone else

It is debatable whether it needs fixing, Tab is not used as often as other methods by screen reader users and with the fact it is only on a brand new session (I mean I have never noticed it and I use a screen reader often, albeit only for testing not as a full time user) I imagine most people will not be affected.

As it only appears to happen if the first text on the page is a link you could work around it perhaps (I haven't had chance to test) by adding a span before it with a space.

<div class="skip-nav">
  <span>&nbsp;</span>
  <a href="#main-content">Skip navigation</a>
</div>

I will return to this question after some testing of the above but it may take a couple of days before I get chance.

Update

I was correct it seems, adding a span with a space fixes the issue and focus is shown correctly.

full HTML tested in the fiddle below, just added <span>&nbsp;</span> into the <header> , the first link then shows focus as expected:

 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>NVDA focus Test</title> </head> <body > <header> <span>&nbsp;</span> <!---------------THIS IS WHAT I ADDED-------------> <a href="#content" id="skipToContent">I should focus on first tab press</a> <a href="#accHelp" id="skipToAccHelp">I should focus on second</a> </header> <section style="margin-top: 20px;"> <p> When you press tab after this page has loaded (at least for me), the initial tab press will focus the <i>second</i> link for some reason. </p> <p> This seems to happen however I present the link (on its own, wrapped in a div, section, or even a ul/li with the list-style set to 'none') :-(. </p> </section> </body> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM