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?