0

There are times when I, a custom theme, a contributed module or library, prevents the default action of an <a> tag. This is not uncommon and needed when implemented.

Something like e.preventDefault().

Now when you hover over the link, browsers will still show the innate link href value, even though the click event is intercepted. Same for bots, scrapers, scripts, anything that reads the DOM.

Examples:

  1. Change href to '#'
  2. Change title attribute ('account-menu-list-activator')
  3. Add aria-label(s)
  4. Or otherwise, alter the link to match it's new UX role.

Does this matter?

Example:

A menu link to a user profile exists in a menu. A new theme/module alters that menu link and adds a caret for the dropdown menu. This theme/module looks for this caret and alters the behavior of the link via jQuery by intercepting the click event. Now the link no longer redirects to the user profile but toggles the dropdown menu.

This assumes (as is usual) that the caret does not have its own click area, and that the <a> tag itself is intercepted because of it.

Code Example (Drupal - Bootstrap Theme):

<ul>
  <li>
    <a href="/user" class="dropdown-toggle" data-toggle="dropdown">Link Text <span class="caret"></span></a>
    <ul class="dropdown-menu">
      <li class="first last">
        <a href="/">Sub Link Text</a>
      </li>
    </ul>
  </li>
  <li class="last">
    <a href="/">Link Text</a>
  </li>
</ul>

caret refers to <span class="caret"></span>.

This link uses classes and data attributes for functionality/behavior, but does not contain aria labels or replace the href (It's a link, not a button).

4
  • 2
    Can you clarifiy what does the link do? If it's not longer a link in the sense that it doesn't redirect you to a new page, but instead starts an action on the same page, then you want to turn it into a <button> element. It can be easily styled to visually look like a link if needed, but in terms of accessibility and usability, it will behave and be announced like a button. If the link has a fallback (if you open it in a new window, does it still work?) then keep it as a link.
    – Victor
    Commented Apr 10, 2019 at 15:19
  • @Victor, I've added an example to my question. Commented Apr 10, 2019 at 15:36
  • 1
    thanks. I'm not too clear what you mean by caret in this instance, but if that new link toggles a dropdown menu then it should definitely be changed to a button instead. Can you provide a screenshot perhaps? If it opens a dropdown menu, you may also want to consider using aria-expanded to let screen reader users know that it's expandable, and whether it is currently expanded or not.
    – Victor
    Commented Apr 10, 2019 at 16:13
  • Thanks, @Victor, I've added the markup for a real use case. I feel I would agree strongly with your comment. Can we back it and provide an answer? Commented Apr 10, 2019 at 16:30

1 Answer 1

1

Following up on the comments with a more complete answer:

This link no longer has the expected behaviour of a link (taking you to another page), but instead opens a menu on the same page. You should change it to a native button element, which will allow you to keep the accessibility benefits (it is keyboard focusable by default, responds to keyboard/touch/mouse events, and interpreted correctly by screen readers and voice command software). You should not use a neutral element (like <span> or <div>) to replace the link, because by default, that would only work with a mouse without unnecessary additional effort. If you are confused about the semantic difference between a link and a button, see this blog post.

Additionally you should use the aria-expanded attribute on the button, to convey its state to assistive technologies. It should be equal to false when it is collapsed, and true when it is opened.

In your example, this would look like this:

<ul>
  <li>
    <button aria-expanded="false" class="dropdown-toggle" data-toggle="dropdown">Link Text <span class="caret"></span></button>
    <ul class="dropdown-menu">
      <li class="first last">
        <a href="/">Sub Link Text</a>
      </li>
    </ul>
  </li>
  <li class="last">
    <a href="/">Link Text</a>
  </li>
</ul>

I presume the caret span is an icon of an arrow. Just a small caveat here: it should normally be ignored by screen readers already, because it is an empty span. However if that graphic is implemented using an icon font and the CSS ::before pseudo-element, it will become focusable by VoiceOver (it won't be announced as anything, but it will 'click' as a separate element). If that's the case, you can add aria-hidden="true" on the caret span, to make sure it is ignored by all screen readers.

You should only use this technique if the dropdown menu appears on click/key press, not on hover or on focus. I really recommend reading this Inclusive Components post on menus if your menu is any more complex than that. That post also explains why you should stay away from things like aria-haspopup or role="menu", which are often misused and can create a worse experience.

1
  • In this instance, it is a click event. A worthy note about the ::before pseudo-element. And adding aria-hidden="true" to the span element might at least help future proof markup... Commented Apr 10, 2019 at 17:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.