When and when not to use role="button"

Whenever i get this question of Buttons vs link I ask myself, is it scripted functionality or a is it Navigation(internal or external)?

  • Buttons activate scripted functionality on a web page (dialogs, expand/collapse - regions).
  • Links take you to another location, either to a different page or different location on the same page.

Coming to a11y

Role tells screen readers and other assitive technology the semantic category of an element, meaning the type of thing that it is. Every element already has a default role of some kind. The <button> element has an implied role="button", and the <img> element has an implied role="img" and so on.

role="button"

  • if you use <button> don't add role (it's implicit)
  • <div role="button"> - (Adding roles do not cause browsers to provide keyboard behaviors or styling). Try to use real <button> If that’s problematic for styling purposes, you can use role="button". Be sure to add tabindex="0" to make it keyboard focusable, and ensure it works with both the Enter key and Spacebar, ensure it has proper disabled, hover, focus state, works in high contrast using media query.

  • Don't use <a role="button"> : it doesn't make sense in any way, it'll give you a block element just like <div> which you can style anyway, remember the question, it is a scripted functionality use <button> or <div role="button"> , if it is a navigation use <a> without any role (style it the way you want)

Also, <a> cannot be disabled, <buttons> can be.

Screen readers have shortcuts to read out all the links eg NVDA user can press

  • K - jumps to Next link
  • INS + F7 it lists all links, headings
  • U Un visited Link Quick Key
  • V Visited Link Quick Key

I also think about do I want screen reader users to hear this link when they press ins + f7 ?

EDIT: I missed to mentions assigning a role to an element overrides its native role. so <a role="button" is no more a role="link" and won't come up in INS + f7 list and as it will be treated by the accessibility API as a button