Preventing Windows Narrator redundant focus in Scan Mode

At my new assignment as an accessibility developer, our main screen readers used for testing are NVDA and Windows Narrator. I hadn’t worked with Windows Narrator before, but have grown accustomed to testing with it almost daily.

Many of the bugs we receive from the routine accessibility testing on new pages are “Redundant Narrator focus in Scan Mode”. That means the screen reader would focus either a decorative element, or the same element repeatedly. The regular mode of Narrator is pretty good for focusing only interactive elements.

The program is supposed to focus every piece of text on the page while in Scan Mode, but the problem arises when the user presses the Down or Up Arrow keys and the focus goes into an element with no electronic text and it doesn’t voice anything, leaving the user confused.

After spending a lot of time investigating, the issue was CSS. Apparently, some properties make the Narrator think that they are real elements and they receive focus, which is bad.

CSS content property

The biggest offender. Issue exists for both Edge Legacy and Chromium. Let’s say we want to add “>” after every link:

a:after{
    content: “>”;
    display: block;
}

Well, tough luck. Narrator would now focus the chevron after reading the link name. You are probably thinking it is not a big deal, but if you have 40 links on one page, it would take ages for the user to finish scanning it.

On Edge Legacy it focuses the symbol if display: block; is applied, and on Edge Chromium it focuses it if either block or inline-block is present.

Even content: “ “ with just space as the only value was creating problems. This is usually used to create a “table” layout for items, without using the <table> element. It’s an old technique that is obsolete. Use flexbox or the grid for layout instead.

content is often used for font icons. So the block below would make all the icons focusable:

a.phone_icon:after{
    content: "\e090";
    font-family: 'ElegantIcons';
    display: inline-block;
    /* Rest of your font icon styles */       
}

Solution

You have two options. You can either use display: inline or inline-flex if you need block-level behaviour, or use ARIA. You have to abstract the element on which the property is applied to and then add aria-hidden=”true” on it, like this:

<a href="tel:1234567890"> 
    1234567890 <span class="phone_icon" aria-hidden="true"></span>
</a>

Block level pseudo classes without content values

This issue only exists for Edge Chromium. Depending on the styles, Narrator might interpret CSS pseudo classes like :before and :after as content, so chances are, it will focus them in Scan Mode.

Let’s adding a chevron as a background image:

a.phone_icon:after{
    content: “”;
    background-image: url('my_image.png');
    display:block;
}

Notice the last rule - if you combine pseudo classes with display:block or inline-block, they will get focused.

Solution

If you still need to maintain a block level element, use display: inline-flex instead of block. It won’t get focused in scan mode, but it will still look the way you want it to be, since inline-flex behaves very similar to inline-block.

Relative positioning

Issue was on Edge Chromium. This one was weird. In my case, I had a full width hero image and Narrator kept focusing on it. It had no pseudo classes or content properties, but after an hour of debugging, it turned out the culprit was relative positioning.

div.hero{
  background: url('my_image.png');
  position: relative;  
}

Solution

The only solution is to remove the relative positioning. Doesn’t seem to have problems with absolute or sticky, just this relative.

Note: I haven’t been able to reproduce the extra focus in my experimental code, however, just keep it in mind in case you get an element focused, it could be the relative positioning.

Conclusion

Narrator has come a long way since Microsoft Sam, but it still has some strange bugs that can take a while to debug. It is imperative to make the browsing experience in Scan Mode as smooth as possible, since it is the default mode and it gives the users a sense of the content on the page and you don’t want them to get stuck or to focus elements with no audio output.

Most screen readers nowadays would read aloud the text added via content property, the reason being is that web developers make the mistake of using the property to convey important information, which is a mistake. That’s why screen readers are trying to adapt and over-correct a bad user interface in order to make it accessible, which unfortunately can result in some obscure bugs that are difficult to track.

In my experience, if Narrator focuses on an element it is not supposed to, the culprit is usually some CSS. I will keep updating the list as I discover new bugs.