Skip to main content

Button vs Link

Use buttons for actions and links for navigation so people can predict what will happen before they activate a control.

Wooden arrow sign boards point in different directions near a cactus.
Photo: Sign Boards Arrow Pointing to a Direction via Pexels — https://www.pexels.com/photo/sign-boards-arrow-pointing-to-a-direction-6405702/
View full screen Download image

Buttons and links are easy to make look the same. They are not the same control.

A link takes someone somewhere. A button does something on the current page or in the current flow.

That difference matters because people build expectations from the control type. Keyboard users, screen reader users, voice control users, and people who rely on browser behavior all use those expectations to move through an interface with less guessing.

The common project moment

A design has several clickable things: a card that opens details, a “Learn more” label, a “Save” action, a “Cancel” control, a menu item, and a link that looks like a button.

Someone asks, “Does it matter whether this is coded as a link or a button if it looks right?”

It does.

The question is not what the control looks like. The question is what happens when someone activates it.

Start with the behavior

Use a link when activation moves the user to another place.

That can mean:

  • another page
  • another route
  • another document
  • another section identified by an anchor
  • a downloadable file
  • an email address, phone number, or external destination

Use a button when activation causes an action.

That can mean:

  • submitting a form
  • saving changes
  • opening or closing a dialog
  • expanding a section
  • applying a filter
  • deleting an item
  • starting, stopping, pausing, or retrying something
  • changing state without navigating away

If the destination changes, start with a link. If the interface state changes, start with a button.

A real link gives people browser behaviors they expect.

People can usually:

  • open it in a new tab or window
  • copy the link address
  • see the destination in the browser status area
  • visit it from a list of links in assistive technology
  • bookmark the destination when appropriate

If a control takes someone to a product detail page, a help article, a record, a dashboard, or a new route, it should normally be an <a href="..."> link.

Do not use a button with JavaScript navigation just because the visual design uses a button-shaped style.

The style can be button-like. The element should still match the behavior.

Buttons should behave like buttons

A real button tells people the control performs an action.

People expect it to work with button keyboard behavior, to be announced as a button, and to change something when activated.

Use a <button> for actions such as:

  • Save
  • Submit
  • Continue
  • Add another item
  • Open filters
  • Close dialog
  • Show password
  • Expand details
  • Remove file
  • Retry upload

Avoid making a link with href="#" act like a button. Avoid putting button behavior on a generic div or span.

Those patterns often create extra keyboard, focus, name, role, and state work that native controls already solve.

Visual style does not decide semantics

A link can look like a plain text link, a card, a nav item, or a prominent call-to-action button.

A button can look quiet, secondary, icon-only, or destructive.

Visual weight is a design decision. Element choice is a behavior decision.

Ask this before implementation:

If someone activates this, are they going somewhere, or are they making something happen?

That answer usually decides the control.

Watch mixed controls in cards, menus, and tables

The button-vs-link problem often shows up inside dense UI.

Common examples:

  • A card title links to a detail page, while a favorite icon button changes saved state.
  • A table row links to a record, while row actions edit, duplicate, archive, or delete the record.
  • A menu item may navigate to a settings page, while another menu item signs the user out.
  • A “Cancel” control may navigate back to a list, close a modal, or clear a form depending on the flow.

Do not make every clickable thing in the region use the same element for convenience.

Each control still needs its own job, name, and expected behavior.

Be careful with disabled, loading, and destructive states

Buttons often have states that links do not have in the same way.

For example:

  • a submit button may be unavailable until required fields are complete
  • a save button may show a loading state
  • a delete button may need confirmation
  • an expand button may expose or hide content
  • a toggle button may switch between pressed and not pressed

If a control has state, make sure the state is not communicated by color alone and is available to assistive technology when needed.

If a link is temporarily unavailable, reconsider whether it should be a link at all, or whether the surrounding flow needs clearer conditions before the link appears.

Questions teams can ask

During design and content

  • Does this control navigate somewhere or perform an action?
  • If it looks like a button but navigates, does the label make the destination clear?
  • If it looks like a link but performs an action, would a button style reduce confusion?
  • Are destructive actions visually and textually distinct from ordinary navigation?
  • Is the visible label enough to predict what happens next?

During development

  • Is navigation implemented with a real href when there is a real destination?
  • Are actions implemented with a native <button> unless there is a strong reason not to?
  • Are custom controls avoiding fake links such as href="#"?
  • Does keyboard behavior match the element role?
  • Does any state change need aria-expanded, aria-pressed, aria-disabled, or a status message?

During QA

  • Can keyboard users tab to the control and activate it predictably?
  • Does a screen reader announce the control as the expected type?
  • Can a link be opened in a new tab when that behavior should be available?
  • Does activation cause the result the label promised?
  • Are focus movement and error/status messages clear after activation?

Common trail hazards

  • Styling a link as a button and then assuming it must be coded as a button.
  • Using a button for navigation because it is easier in a JavaScript framework.
  • Using href="#" or javascript:void(0) as a fake button.
  • Making a card, row, or tile one large click target without preserving meaningful internal controls.
  • Changing interface state without a clear label, state, or status message.
  • Using only color to show that an action is disabled, selected, active, or destructive.
  • Treating “Cancel” as one pattern when it may mean close, reset, go back, or abandon changes.

Small habit

When reviewing a clickable control, say the sentence out loud:

This control is a [link/button] because it [goes somewhere/does something].

If the sentence feels awkward, the control probably needs a clearer element, label, or flow decision.

What to do next

If you are reviewing a screen, pick three clickable controls and identify whether each one goes somewhere or does something. If one of them is custom, check ARIA Is Not Duct Tape before treating ARIA as the fix.

Then check whether the code, label, visual treatment, keyboard behavior, and result all match that decision.