Skip to content
Website Accessibility

Buttons vs Links: Which to Use for Accessibility

A link takes people somewhere and a button does something on the page. Mixing them up breaks keyboards and confuses screen readers. How to tell and how to fix it.

7 sections · 8 min read
In this article · 7 sections

A keyboard user tabs through your homepage and the “Get a quote” control is skipped entirely. Someone using a screen reader hears “link” on your menu toggle, presses Enter, and nothing happens. A third visitor opens the “Add to cart” control in a new tab out of habit and lands on a blank page. All three come from the same mix-up: something that should be a button was built as a link, or something that should be a link was built as neither.

The buttons vs links accessibility question sounds like developer trivia, but it shapes how every control on your site behaves for people who do not use a mouse. This post explains the rule of thumb, the problems that show up on WordPress and page-builder sites, and how to check your own pages.

A link takes the user to a new place: another page, a section further down, a file, an email address. A button performs an action on the current page: submits a form, opens a menu, plays a video, adds an item to a cart, shows more results.

That is the whole rule, and it matters because browsers and assistive technology treat the two differently:

How links and buttons behave by default
Behavior Link Button
Announced by screen readers as “link” “button”
Activated by Enter Enter or Space
Shows in a screen reader’s links list Yes No (it has its own controls list)
Can open in a new tab Yes No
What users expect Page or view changes Something happens here

When the element matches the job, users get what they expect without anyone writing extra code. When it does not, people get surprises, and someone has to patch the gap with ARIA and JavaScript.

Looks are a separate matter. A link can be styled as a big colored “button”, and that is fine. “Book now” that goes to a booking page is a link, even if it is a rounded orange box. What counts is the element in the code, not the shape on screen.

Common mix-ups on business websites

Older themes and plugins often use an anchor with href="#" or a JavaScript address to open a menu, a popup or a search panel. Screen readers announce it as a link, so users expect to go somewhere. Space bar does nothing, and if JavaScript fails or someone opens it in a new tab, they get nowhere. These should be buttons.

The div pretending to be a button

This is the bigger problem. A designer wants a clickable box, so the developer puts a click handler on a div or span. It works with a mouse. It does not appear in the Tab order, it is not announced as a control, and Enter and Space do nothing. Keyboard users cannot use it at all, which fails 2.1.1 Keyboard, and screen readers have nothing to report, which fails 4.1.2 Name, Role, Value.

<!-- Mouse only, invisible to keyboard and screen readers -->
<div class="open-menu" onclick="openMenu()">Menu</div>

<!-- Works for everyone, no extra code needed -->
<button type="button" class="open-menu" aria-expanded="false">Menu</button>

You can make a div behave like a button with a role, a tabindex and key handlers for Enter and Space. But the native button does all of that for free, and it keeps working when the next update changes the script. Use it.

Buttons used for navigation

The reverse happens too. A “Contact us” button in a form plugin or page builder that runs a script to change the page location. It cannot be opened in a new tab, it does not show in a links list, and it is announced as a button when it acts like a link. If it goes to a page, make it a link.

Whole cards that are clickable

Service cards and blog cards are often wrapped so the whole box is one big link. That can be fine, but when the card contains a heading, an excerpt, a price and a “Learn more” label, the screen reader may read all of it as one very long link name. A better pattern links the heading and lets the rest of the card stay as plain text, sometimes with a CSS technique that stretches the click area over the whole card.

Accessible buttons need clear names

Every button needs a name a screen reader can say. For a text button, the name is its visible text, so make that text describe the action: “Send message”, “Add to cart”, “Show 10 more reviews”. “Submit”, “Go” and “OK” are vague once they are read out of context.

Icon-only buttons are where names go missing most often: the hamburger menu, the magnifying glass for search, the X on a popup, the heart for a wishlist. Without a name, a screen reader says just “button”, and a page full of them sounds like “button, button, button”. Give each one a name, either with visually hidden text inside the button, as below using the screen-reader-text class many WordPress themes already include, or with aria-label.

<button type="button" class="popup-close">
  <span class="screen-reader-text">Close newsletter signup</span>
  <svg class="icon-x" aria-hidden="true"><!-- X shape --></svg>
</button>

Keep the name close to any visible text. If a button shows the word “Search”, its accessible name should contain “Search” too, so voice control users can say what they see. When to use ARIA and when it backfires is covered in our post on how aria-label works, and the icons themselves get their own treatment in our guide to accessible icons.

Button states: pressed, expanded, disabled

Some buttons change state, and sighted users see it. A menu toggle opens a panel. A filter chip turns on. A “Save” button grays out until a form is complete. Screen reader users need the same information.

  • Expanded or collapsed. Buttons that show and hide content, such as menus and accordions, should use aria-expanded set to true or false as they change. Our post on the accessible dropdown menu shows this on navigation.
  • On or off. Toggle buttons, like “Show only in stock”, can use aria-pressed.
  • Disabled. A disabled button cannot be focused in most browsers, so a keyboard user may never find out it exists or why it is unavailable. Many teams prefer to leave the button enabled and show a clear message if the form is incomplete.
  • Busy. After a click, if the button triggers a slow action, change its text (“Sending…”) and announce the result when it finishes, so the user does not click again.

Buttons also need a visible focus outline and enough size and contrast to find. If you tab to a button and cannot see where you are, that is a styling fault rather than a buttons vs links one, explained in our post on visible focus indicators.

Where this shows up in WordPress

The block editor’s Buttons block creates links styled as buttons, which is right for “Book a call” or “View menu” that go to another page. It is not meant for actions on the page itself. For those, you need the element that your form plugin, theme or a developer outputs.

Page builders vary. Some button widgets can be set as links only. Some popup, accordion and tab widgets output proper buttons; others output divs or empty links. Theme menu toggles and search icons are frequent offenders. Store controls such as add to cart and quantity steppers deserve a check too, because themes and add-ons often replace the default markup with their own. If a control on your site is not clickable at all, our post on buttons that will not click covers the non-accessibility causes.

How to check your own site

  1. Tab through each template. Every control you can click with a mouse should receive focus. Anything skipped is likely a div or span with a click handler.
  2. Try both keys. On each button, press Space as well as Enter. If Space scrolls the page instead, it is probably a link pretending to be a button.
  3. Listen to it. With NVDA or VoiceOver, move through the page. Does each control say “link” or “button” correctly? Does each have a name that matches what you see?
  4. Check the states. Open a menu or accordion with a screen reader running. It should announce “expanded” and then “collapsed”.
  5. Right-click links. Real links offer “Open in new tab”. If a control that goes to another page does not, it is not a real link.

Most of these fixes are small once found, but they usually live in theme or plugin templates, so they need a developer rather than an editor. For how buttons fit alongside headings, images and the rest of the content side, see our guide to accessible content for editors, and for the broader process of audits and fixes, our ADA website accessibility help page explains the approach.

Frequently asked questions

No. Styling is up to you. A link that goes to a booking page can look like a large colored button and still be accessible, because it behaves like a link and is announced as one. The problem is only when the underlying element does not match what the control does, such as a link that opens a menu.

Why does the Space key matter for buttons?

Native buttons respond to both Enter and Space, and keyboard and screen reader users expect that. Links respond only to Enter. If a control looks and sounds like a button but ignores Space, it is usually a link or a scripted div, and some users will think it is broken when they press the key they normally use.

Can I fix div buttons with ARIA instead of rebuilding them?

You can add a button role, a tabindex and keyboard handlers, but that means more code to maintain and more ways to get it wrong. Replacing the div with a native button element is usually simpler and more reliable. ARIA is a reasonable stopgap when a plugin’s markup cannot be changed, as long as it is tested.

What should icon-only buttons be called?

Name them after the action, not the picture. A magnifying glass that opens search should be called Search, not magnifying glass. A close icon on a popup should say what it closes, such as Close cart or Close newsletter signup. The name can come from hidden text inside the button or an aria-label.

When an audit finds div buttons and fake links in every template, it usually points to a theme or builder setup that will keep producing them. In that case it can make more sense to plan an accessible website redesign that starts from sound components than to patch each control one at a time.

Next in this series: Animation Accessibility: Parallax, Video and Reduce Motion