Skip to main content

If you need a link, don’t use a button

Posted in Accessibility, Design and Development

I’ve written about when links need to look like buttons, but what about when a button might need to look like a link?

Thankfully, the case for doing this is much less common. And that’s just as well since it’s a lot more problematic than the other way round.

Note: everything in this article also applies to rolling your own links using a <span> element.

Semantics/role

First up, override the semantics using ARIA. Alarm bells should be going off here, as this breaks the Second Rule of ARIA Use:

Do not change native semantics, unless you really have to.

But if we have to, adding role="link" will let users of assistive technology like speech recognition software access if they call it out as a “link”; it’ll also let screen reader users know that they’ve arrived on a link.

Behaviour

Next, we need to get our <button> to behave like a link (<a>).

Another note: the <a> element needs an href attribute in order to behave properly.

Draggable

Links are draggable, so we need to add draggable="true", but we also need to make the dragged link behave correctly, so it should be able to be dropped in:

  • the browser’s tab bar to open the link in a new tab
  • a Finder (or File Explorer on Windows) window to save a shortcut/bookmark to the page

Can this be done with JavaScript? I’m no JavaScript expert, but I wouldn’t have thought so since it’s stuff that happens outside the webpage and, with the latter behaviour, the browser application itself.

Keyboard use

Unline a button, a link that has keyboard focus isn’t activated when the Space key is pressed; only Return/Enter. Instead, Space scroll the page down; unsurprisingly there’s some fiddliness here as the amount the page scrolls differs between operating systems:

  • On Mac it scrolls the page by very slightly less than the full height of the browser viewport
  • On Windows it scrolls the page about three quarters of the height of the browser viewport

To ensure the experience matches our users’ expectations, we probably need to veer into ‘browser sniffing’ territory, which is a big red flag.

Actions

We also need to offer the expected set of actions in our context menu; things like:

  • Open in new tab
  • Open in new window
  • Open in private window
  • Open in tab group
  • Copy link
  • Copy link title
  • Download/save linked file
  • Add link to bookmarks
  • Add link to Reading List
  • Share

Ideally this menu should be native, and be presented along side the default right click actions for elements that contain text (which varies from browser to browser…), like dictionary look-up, translation, and speak aloud. There are some good tutorials on creating a custom context menu, but I don’t think it can be done natively.

Don’t do it

Even if we could do it, this is one where we really shouldn’t. Links are not only one of the most common HTML elements, but one of the most complex; if a button needs to be presented as a link, we should use the <a> element rather than fighting a losing battle using ARIA and JavaScript.

Accessibility in your inbox

I send an accessibility-centric newsletter on the last day of every month, containing:

  • A roundup of the articles I’ve posted
  • A hot pick from my archives
  • Some interesting posts from around the web

I don’t collect any data on when, where or if people open the emails I send them. Your email will only be used to send you newsletters and will never be passed on. You can unsubscribe at any time.

More posts

Here are a couple more posts for you to enjoy. If that’s not enough, have a look at the full list.

  1. Avatars and alt text

    I really enjoyed Nicolas Steenhout’s recent article on Alt text for avatars or user photos. But there is a context where I would break his rule…

  2. Upgrading from iPhone 13 mini to 16 Pro

    I get a new phone every 3-ish years, give mine to my wife, and now she gives hers to our daughter. I got a 16 Pro this year! Here’s the skinny.