EN UA

Accessible React Button and Link Component

Button or link? <button> or <a>?

A React component that automatically selects the correct HTML element and ensures accessibility.

One component — multiple scenarios

Button
Screenshot of a blue button with the text Open modal.
Disabled button
Screenshot of a disabled light blue button with the text Open modal.
Link
Screenshot of a link with the text Contact page.
Link styled as a button
Screenshot of a blue button-like link with the text My profile.

Key features

  • Automatically chooses between <button> and <a> based on the provided props
  • Written in TypeScript and suitable for modern projects
  • Provides correct disabled state behavior
  • Appearance is independent of functionality and controlled through props
  • Supports custom styles through your own classes
  • Ensures accessibility and complies with WCAG 2.2 requirements
  • Supports keyboard navigation and screen readers

Usage examples

As a button

Code example
<Action
  onClick={() => {
    // your code
  }}
>
  Open modal
</Action>
Result (screenshot)
Screenshot of a blue button with the text Open modal.

As a disabled button

Code example
<Action
  onClick={() => {
    // your code
  }}
  disabled
>
  Open modal
</Action>
Result (screenshot)
Screenshot of a disabled light blue button with the text Open modal.

As a link

Code example
<Action
  href="/contacts"
  target="_blank"
>
  Contact page
</Action>
Result (screenshot)
Screenshot of a link with the text Contact page.

As a button-styled link

Code example
<Action
  href="/profile"
  variant="button"
>
  My profile
</Action>
Result (screenshot)
Screenshot of a blue button-like link with the text My profile.

Which tag should you choose — <button> or <a>?
A common problem in React interfaces

The challenge of choosing the correct semantic element appears in the “button or link in React” scenario, when a link looks like a button or a button looks like a link. When should you use <button>, and when should you use <a>?

There is a simple rule: if clicking an interactive element navigates to another page or another location within the same page, you should use the <a> element.

However, despite this well-known rule, developers often face the dilemma of choosing the correct semantic element.

Using <button> when a link should be used creates obstacles for keyboard navigation and can make screen reader navigation significantly more difficult.

ARIA attributes are sometimes used to compensate for incorrect HTML semantics in buttons and links, but this often creates additional accessibility issues.

How the component works

Semantics

The component automatically chooses the appropriate semantic element:

  • <a> when the href prop is provided, meaning the element behaves as a link
  • <button> when the onClick prop is provided, meaning the element behaves as a button

Appearance

A separate prop controls the appearance of the element. You do not need to spend time overriding native HTML styles. Instead, you can specify the desired appearance with a single prop. This makes it possible to create a link that looks like a button or a button that looks like a link.

Styles

The component includes built-in styles, but a prop allows you to disable them.

You can also customize the appearance using your own CSS classes.

Disabled

The component provides correct disabled behavior for buttons and links while taking accessibility requirements into account.

Additional props

Separate props allow you to configure link attributes such as target or rel, and also specify the button type (submit or another type).

Accessibility

WCAG 2.2

  • Semantic HTML elements
  • 7:1 contrast ratio (with built-in styles)
  • Minimum size of 44×44 px (with built-in styles)

Keyboard navigation

  • Keyboard navigation support
  • Visible focus indicator
  • Disabled elements are removed from the tab order

Screen reader support

  • Screen reader navigation
  • Elements are announced correctly by screen readers
  • Support for custom aria-label attributes

Want to use this component in your project?

Fill out the form, and we'll let you know when it becomes available for purchase.