Question

Disable Links with CSS: pointer-events and Accessible Alternatives

htmlcss

Question

Is it possible to disable a link using only CSS? I have a class named current-page, and I want links with that class to perform no action when clicked.

Short Answer

You will learn what CSS can and cannot do to an HTML link. In particular, you will see how pointer-events: none blocks mouse and touch interaction, why it does not fully disable a link for keyboard users, and how to mark the current navigation page accessibly.

Concept

An anchor element (<a>) becomes a navigable link when it has an href attribute.

<a href="/about">About</a>

CSS controls presentation and some pointer interaction, but it does not change the HTML meaning or built-in keyboard behavior of an element. The commonly used CSS rule is:

.current-page {
  pointer-events: none;
}

This prevents pointer events such as mouse clicks and taps from reaching the link. It is useful when a navigation menu includes a link to the page currently being viewed.

However, this is not a complete disabled state:

  • A link with href can still receive keyboard focus.
  • Pressing Enter can still follow the link in many browsers.
  • Screen readers can still announce it as a link.

HTML does not provide a native disabled attribute for <a> elements. The most accurate solution for a current-page navigation item is usually to render it as non-link text and indicate the current page with aria-current="page".

Mental Model

Think of CSS as the paint and layout of a building, while HTML supplies the doors and their purpose.

pointer-events: none puts a sign over a door saying, “Do not open with your hand.” A mouse or finger cannot use it. But the door is still a door: someone using a keyboard may still reach and open it.

To truly make a current navigation item non-clickable, do not create a door at all. Render ordinary text instead, and label it as the current location.

Take Quiz

Syntax and Examples

Use pointer-events: none to prevent mouse and touch interaction.

.current-page {
  pointer-events: none;
  cursor: default;
  color: #666;
  text-decoration: none;
}
<nav aria-label="Main navigation">
  <a href="/">Home</a>
  <a href="/products" class="current-page">Products</a>
  <a href="/contact">Contact</a>
</nav>

The Products link will not respond to a mouse click or tap. The cursor: default rule avoids showing a hand cursor, and the remaining rules make the item look inactive.

For a current-page menu item, prefer non-link markup:

<nav aria-label="Main navigation">
  <a href="/">Home</a>
  <span class="current-page" aria-current="page">Products</span>
  <a href="/contact">Contact</a>
</nav>
.current-page {
  color: #666;
  font-weight: bold;
}

Here, Products is text rather than a link, so it cannot be clicked or activated with a keyboard. aria-current="page" tells assistive technology that this item represents the current page.

Step by Step Execution

Consider this CSS-only version:

<a href="/products" class="current-page">Products</a>
.current-page {
  pointer-events: none;
}

What happens:

  1. The browser reads the <a> element and sees href="/products", so it creates a real link.
  2. The browser applies the current-page class.
  3. CSS applies pointer-events: none.
  4. A mouse click or touch event does not target the link, so pointer interaction does not navigate.
  5. The link still has an href, so it may remain in the keyboard tab order.
  6. A keyboard user can focus it and may activate it with Enter.

Now compare the semantic version:

<span class="current-page" aria-current="page">Products</span>
  1. The browser reads a <span>, which is ordinary text, not a link.
  2. There is no href and no built-in link behavior.
  3. It is not normally keyboard-focusable.
  4. aria-current="page" communicates that Products is the page currently being viewed.
  5. No click or keyboard navigation action exists to disable.

Real World Use Cases

  • Site navigation: Show the visitor which page is currently open without linking to the same URL again.
  • Breadcrumbs: Mark the final breadcrumb as the current page rather than making it a link.
  • Pagination: Prevent interaction with the button or page item representing the active page.
  • Temporarily blocked UI: Use pointer-events: none while a panel is visually loading, but also use application logic to prevent actions.
  • Read-only displays: Render labels or status values as text instead of links when navigation is not available.

For controls that start an action, such as submitting, saving, or deleting, use a <button> rather than an anchor. Buttons support the real disabled attribute.

Take Quiz

Real Codebase Usage

In production navigation components, developers usually conditionally render a link only when it points somewhere different from the current route.

<nav aria-label="Main navigation">
  <a href="/dashboard">Dashboard</a>
  <span aria-current="page" class="nav-item nav-item--current">Reports</span>
  <a href="/settings">Settings</a>
</nav>

A server-side template, React component, or other UI framework can make this decision based on the current route.

A typical pattern is:

  • If the item is the current route, render text with aria-current="page".
  • Otherwise, render an <a> element with a valid href.

For temporarily unavailable actions, code should enforce the rule too. CSS is visual and pointer-focused; JavaScript or server-side authorization must still prevent an action that is not allowed. For example, an API must reject a request from a user without permission even if the corresponding UI control looks disabled.

Common Mistakes

Assuming CSS fully disables an anchor

.current-page {
  pointer-events: none;
}

This blocks pointer interaction, but it does not reliably stop keyboard activation. Use non-link text for a current page, or handle the behavior in JavaScript when an item must remain an anchor.

Using disabled on an anchor

<a href="/products" disabled>Products</a>

disabled is not a supported disabling mechanism for <a>. Browsers do not treat this as a disabled link. It may exist as an attribute in the DOM, but it does not remove link behavior.

Using only aria-disabled="true"

<a href="/products" aria-disabled="true">Products</a>

aria-disabled communicates a state to assistive technology, but it does not block navigation by itself. If an anchor is actually disabled, code must prevent its behavior, and its focus behavior needs deliberate design.

Removing only the href without considering styling

<a class="current-page">Products</a>

Without href, the element is no longer a real link, which may be appropriate. However, a <span> is usually clearer for plain text. Also ensure the CSS does not still make it look clickable.

Disabling an entire parent container accidentally

nav {
  pointer-events: none;
}

This disables pointer interactions for every child in the navigation area. Apply the class only to the current item.

Relying on the UI for security

A disabled-looking link does not protect data or routes. Authorization must be checked by the server or API.

Comparisons

ApproachBlocks mouse/touch?Blocks keyboard activation?Semantic meaningBest use
pointer-events: none on <a href>YesNo, not reliablyStill a linkVisual/pointer-only blocking
Remove href from <a>YesYes, as a normal linkNo longer a linkLegacy markup where changing the element is difficult
Use <span aria-current="page">YesYesCurrent non-link itemCurrent navigation page
<button disabled>YesYesDisabled buttonDisabled actions, not navigation
aria-disabled="true" aloneNoNoAnnounces disabled stateNever sufficient by itself

A link navigates to a location. A button performs an action. Choose the element based on what the user is meant to do, then use its native behavior where possible.

Take Quiz

Cheat Sheet

/* Blocks mouse and touch input only */
.current-page {
  pointer-events: none;
  cursor: default;
}
<!-- Preferred for the current navigation page -->
<span class="current-page" aria-current="page">Products</span>
<!-- A real link to another page -->
<a href="/products">Products</a>
<!-- Native disabled behavior is for buttons -->
<button disabled>Save</button>

Key rules:

  • <a href="..."> is a link.
  • CSS cannot reliably make an href link fully disabled for every input method.
  • pointer-events: none affects pointer input, not link semantics.
  • disabled works on buttons and certain form controls, not anchors.
  • Use aria-current="page" to identify the current item in page navigation.
  • Use aria-disabled only alongside behavior that genuinely prevents the action.

FAQ

Can I disable an <a> tag with CSS only?

You can stop mouse and touch clicks with pointer-events: none, but CSS alone does not reliably prevent keyboard users from activating an anchor that still has an href.

Does pointer-events: none disable a link?

It disables pointer interaction with the link. It does not remove the link's href, semantics, or dependable keyboard activation behavior.

Why does the disabled attribute not work on links?

HTML defines native disabled behavior for form controls such as <button>, not for <a> elements.

What is the accessible way to show the current page in navigation?

Render the current item as non-link text and add aria-current="page":

<span aria-current="page">Products</span>

Should I use a link or a button?

Use a link for navigation to a URL. Use a button for an action such as opening a dialog, saving data, or submitting a form.

Is aria-disabled="true" enough to disable an anchor?

No. It announces a disabled state but does not prevent the browser from following the link. The actual behavior must also be prevented.

Is it harmful if a current-page link still works?

It is usually better UX to identify the current page without offering a redundant link. More importantly, avoid creating a control that appears disabled for mouse users but works differently for keyboard users.

Take Quiz

Mini Project

Description

Build a small navigation menu that shows the active page without creating a redundant, clickable current-page link. This models the pattern commonly used in site headers and dashboards.

Goal

Create an accessible navigation bar where the current item is visually highlighted and cannot be activated as a link.

Requirements

  1. Create a navigation area with at least three page items.
  2. Make two items normal links with href values.
  3. Render the current page item as non-link text.
  4. Add aria-current="page" to the current item.
  5. Style the current item so it is visually distinct and does not look clickable.
Take Quiz

Keep learning

Related questions

View more