nvaccess/nvda

NVDA unable to access links in browse mode on certain web pages

Opened this issue · 20 comments

Steps to reproduce:

  1. Access the sample site at https://khsruru.com/title_test.html
  2. Use the latest version of NVDA (2024.1 or the latest alpha version)
  3. Enter the site and use the up or down arrow keys to read the content, which includes several book volumes followed by "View Details" links
  4. Try to access the links using the Tab key or the up and down arrow keys

Actual behavior:

None of the "View Details" links are accessible using NVDA's browse mode or by pressing the Tab key. The links are read as "blank" when navigating with the Tab key.

Expected behavior:

The "View Details" links should be accessible and readable using NVDA's browse mode and the Tab key, similar to how they are accessible with other screen readers like VoiceOver on iOS and TalkBack on Android.

NVDA logs, crash dumps and other attachments:

N/A

System configuration

NVDA installed/portable/running from source:

Installed

NVDA version:

2024.1 or latest alpha version

Windows version:

Windows 11

Name and version of other software in use when reproducing the issue:

Latest versions of Google Chrome and Mozilla Firefox

Other information about your system:

N/A

Other questions

Does the issue still occur after restarting your computer?

Yes

Have you tried any other versions of NVDA? If so, please report their behaviors.

The issue persists in both NVDA 2024.1 and the latest alpha version.

If NVDA add-ons are disabled, is your problem still occurring?

Yes

Does the issue still occur after you run the COM Registration Fixing Tool in NVDA's tools menu?

Yes

The divs with the links inside them need a role="link" since divs do not have semantics by default and so the link is not rendered in browse mode.
https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles
Closing as invalid since this is realted to bad web authoring.

@Adriani90 Oh, unfortunately, it seems you have misanalyzed the source code. Each content section is followed by an <a href> tag. Please verify this again.
Ah, I understand why you might have misunderstood. When using browse mode and navigating with the up and down arrow keys, the links themselves are not accessible. This might have led you to believe that there are no links. Could you please try pressing the Tab key instead? Also, open the developer tools to check the relevant code. Thank you.

@Adriani90 Hmm, the div is merely a container for the <a> tag. Furthermore, even if your logic is correct, there is one issue. If the error were due to not specifying the role for the div, the text for the <a> tag should still be exposed in browse mode. The absence of a role doesn't cause the text to be omitted. This isn't a role issue, but rather a problem with the information being omitted in browse mode. Additionally, please check the accessibility tree. Thank you.

@Adriani90 A div does not need a role just to contain a href. Open the following in a browser address bar:

data:text/html,<div>This is a link <a href="https://link.here">fake link</a>.</div>

The link is still treated as a link.
What you're talking about is documented in detail here, and is frowned upon as I understand it.

The true problem here is that the anchor element has no text content.

Good:

<a href="https://something" title="The title">fiction details</a>

Bad:

<a href="https://something" title="The title"></a>

That is why these links don't render. If I add content to one of the links given in the sample page, it renders just fine, including the title.

What I haven't been able to figure out--and I don't know if I'm just missing it on W3C and Mozilla, or if it's really not there--is if the text content is required by the spec.
Related: what is the browser visually doing with these links that don't have content? Is it only NVDA which doesn't recognize them as links, or is the browser not presenting them as links because they have no content, and are therefore zero-width?

Reopening pending clarification from @jcsteh or someone with more HTML depth than I, about what the browser is actually showing.

A link with no content will generally render with either a width of 0, a height of 0 or both, resulting in it being invisible. These do appear in the accessibility tree, but NVDA ignores them because of the 0 width/height.

Narrator reports these links, as does Voiceover on iOS. Not sure whether that is proper behavior, but that's what happens.

@jcsteh That's what I thought. But can that be overridden by css? I think that is what is being done here, although that's just based on the class name given on the anchor.

"Proper" is debatable. The 0 width/height rule was implemented in NVDA a long time ago to try to remove clutter that wasn't intended to be there due to authoring error. It usually doesn't make a lot of sense for a screen reader user to interact with some element that isn't visible at all. On the other hand, the web has moved on and I've seen quite a few cases where there are 0 width/height elements, but there is an alternative visual rendering. I'd argue that this too is bad authoring, but such is life and I now suspect that the latter kind of bad authoring might outweigh the former, though I have no actual data or evidence to back this up. However, the fact that other screen readers don't apply this rule is another factor to consider. Given all of this, I personally think it might be time for NVDA to try removing this rule and see what happens.

Sure, if you set display: inline-block or similar, you can override the width and height with CSS. But then NVDA will render the link.

data:text/html,a<a href="/" style="width: 1px; height: 1px; display: inline-block;" title="This is a poorly authored link with an overridden width/height and a title but no content"></a>
or even just:
data:text/html,a<a href="/" style="width: 1px; height: 1px; display: inline-block;">

@khsbory What is the CSS of the "stretched-link" class that you have on these links?
I can not seem to load the CSS file independently.

See also #16398. While that particular case is probably a Firefox bug (the CSS is 1px, not 0px, but Firefox somehow gets confused), this kind of quirky behaviour is becoming increasingly common due to the misguided technique of creating an accessible off-screen control which mirrors an inaccessible on-screen control.

I could reproduce this both in Chromium and Firefox, not sure if this is related to css.
Here is the distiled case from the website:

data:text/html,<p>3,245 books</p><div><a href="/book/div/list.dtb?ubdParentCode=100"%20class="stretched-link"%20title="View%20Fiction/Literature%20details"</a></div>

The link has a title, but this seems not to be rendered in browse mode.
Adding role="link" to the div makes it work with NVDA.

However I guess the div needs also an onclick event to work properly.

I think NVDA has some real problems in handling divs in browse mode. This issue is for example related to #15109. The child button inside the div is not rendered in browse mode, but the link is rendered because the div has the coresponding role:
https://codepen.io/bhantp/pen/MWzOmEL

@jcsteh as far as I understand mdn, accessible divs with interactive child elements should have a role and an onclick event. But I might be wron here.
If I didn't misunderstood something, every interactive child element in a div would have to be wrapped itself into a div with role and onclick event. in order for the interaction to work in browse mode.

As others have said, the problem is that the link has no content and it is rendered as 0-width, 0-height. However, this pseudo-link has also another (empty) content through an ::after pseudoelement which is absolutely positioned to create an invisible clickable layer that extends to the full width and height of its parent div (specifically, to its first relatively-positioned container). The CSS for that pseudoelement is the following:

.stretched-link::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
    content: ""
}

The code is certainly a bit strange, but according to the accessible name calculation algorythm, and since the link has no aria-labelledby, nor aria-label, nor real content, the title should probably act as a fallback to provide the accessible name for the link.

However, I can see a big problem with that approach, because the invisible layer created by the ::after pseudoelement will "obscure" the content below it. Therefore, mouse/tactile screenreader users will be unable to read the visible content when hovering/touching it. This is a common mechanism for low vision users that rely on the screen reader to read the text, and probably also for users with reading difficulties.

Thank you for taking a deep interest in the issue I raised. Firstly, this issue should be divided into two separate discussions:

  1. This method is not a correct web development technique.
  2. However, what I want to point out is that, despite this, there are numerous web pages and various cases where NVDA should support these examples, even if they are not fully accessible. From a code perspective, the a tag only has a title attribute, but in the accessibility tree, it is still exposed as a link.
1. This method is not a correct web development technique.

Correct, but since we've established this, I don't think this needs to be discussed any further here. If anyone would like to discuss this further, please open a discussion. Thanks.

2. However, what I want to point out is that, despite this, there are numerous web pages and various cases where NVDA should support these examples, even if they are not fully accessible. From a code perspective, the `a` tag only has a title attribute, but in the accessibility tree, it is still exposed as a link.

I'm inclined to agree as per #16552 (comment), but a final decision needs to be made by the core developers, at which time this issue will be triaged appropriately. Unless anyone has additional information to provide here, I would suggest that there is nothing further to discuss until that decision has been made. Thanks to everyone for their valuable input.