Question
Is there a way to disable a link using only CSS?
I have a class called current-page, and I want links with this class to behave as disabled so that clicking them does not trigger any action.
Example:
<a href="/about" class="current-page">About</a>
Short Answer
By the end of this page, you will understand why CSS alone cannot truly disable an HTML link, what CSS can do visually, and the practical ways developers handle inactive or current-page links using HTML, CSS, and sometimes JavaScript.
Concept
A link (<a>) is an interactive HTML element. Its behavior comes from the browser and the href attribute, not from CSS.
CSS is mainly responsible for presentation:
- colors
- spacing
- fonts
- layout
- visual states
CSS does not normally change the meaning or built-in behavior of HTML elements in a reliable, semantic way. That means CSS can make a link look disabled, but it cannot truly turn a real link into a non-link in the same way a disabled attribute works on form controls like buttons.
For example, this CSS can make a link appear inactive:
.current-page {
color: gray;
text-decoration: none;
cursor: default;
}
But if the element still has an href, it is still a link.
A commonly used CSS rule is:
.current-page {
pointer-events: none;
}
This prevents mouse clicks in many modern browsers, but it is still not a complete or semantic "disabled" state:
- keyboard navigation may still matter in some contexts
- screen readers still treat it based on the HTML
- the element is still structurally a link if
hrefexists
So the important idea is:
- CSS changes appearance
- HTML defines meaning
- JavaScript can change behavior
If a link should not be clickable because it represents the current page, the best solution is often to avoid making it an active link in the first place, or to mark it clearly as the current page with accessible markup.
Mental Model
Think of HTML as the structure and purpose of a building, CSS as the paint and decoration, and JavaScript as the moving parts.
If a door is built into the wall, painting it gray does not remove the door. It only changes how it looks.
A link with an href is like that door:
- HTML says: "this is a door you can use"
- CSS says: "paint it gray"
- JavaScript says: "block the door from opening"
So if you want a link to be truly inactive, the best fix is often to change the HTML or behavior, not just the styling.
Syntax and Examples
If your goal is to make the current page link look inactive, here are the main approaches.
1. Visual-only CSS styling
<a href="/about" class="current-page">About</a>
.current-page {
color: #777;
text-decoration: none;
cursor: default;
}
This only changes appearance. The link still works.
2. Prevent pointer clicks with CSS
<a href="/about" class="current-page">About</a>
.current-page {
pointer-events: none;
color: #777;
text-decoration: none;
cursor: default;
}
This stops mouse interaction in many cases, so clicking does nothing. However, this is not a full semantic disabled state.
3. Better HTML for the current page
If the item represents the page the user is already on, you may not need a clickable link at all.
<span class="current-page" aria-current="page">About</span>
.current-page {
color: #777;
font-weight: bold;
}
This is often the clearest option when the current navigation item should not navigate anywhere.
4. Keep the link, but identify it as the current page
<a href="/about" aria-current="page" class="current-page">About</a>
.current-page {
color: #777;
text-decoration: none;
}
This keeps the link active but tells assistive technologies that this item is the current page.
5. Disable behavior with JavaScript
<a href="/about" class="current-page">About</a>
document.querySelectorAll('.current-page').forEach(link => {
link.addEventListener('click', event => {
event.preventDefault();
});
});
This actually stops the default navigation behavior when clicked.
Step by Step Execution
Consider this example:
<a href="/about" class="current-page">About</a>
.current-page {
pointer-events: none;
color: gray;
}
What happens step by step
- The browser reads the HTML.
- It sees an
<a>element with anhrefof/about. - Because it has an
href, the browser treats it as a link. - The browser then applies the CSS.
color: gray;changes the text color.pointer-events: none;tells the browser to ignore pointer interactions like mouse clicks on that element.- If the user tries to click with the mouse, nothing happens.
- But the element is still an anchor in the HTML, so this is still not the same as removing or disabling the link semantically.
Now compare that with JavaScript:
<a href="/about" class="current-page">About</a>
const link = document.querySelector('.current-page');
link.addEventListener('click', event => {
event.preventDefault();
});
Step by step
- The browser creates the link from the HTML.
- JavaScript finds the element with class
current-page. - A click event listener is attached.
- When the user clicks the link, the event fires.
event.preventDefault()stops the browser's default action.- Since the default action for a link is navigation, the page does not change.
This is a behavior-based solution, not just a styling-based one.
Real World Use Cases
This concept appears often in navigation and UI design.
Current page in a navigation menu
A site menu often highlights the page the user is already viewing.
Example:
- Home
- About
- Contact
If the user is already on About, developers may:
- style it differently
- mark it with
aria-current="page" - leave it clickable
- or render it as plain text instead of a link
Temporarily inactive actions
Sometimes a UI shows an action that is unavailable, such as:
- "Upgrade" only for admins
- "Download" before a file is ready
- "Continue" until required data is filled in
In these cases, a button is often better than a link because buttons support disabled semantics more naturally.
Menu items controlled by permissions
In dashboards, some links may appear unavailable to certain users. Developers usually do one of these:
- hide the link entirely
- replace it with text
- show the link but intercept it with JavaScript and show a message
Documentation or tab navigation
Sometimes the current tab or current section is displayed in the same layout as links, but it should not be clicked again. A non-link element styled like the rest of the navigation is often the cleanest solution.
Real Codebase Usage
In real projects, developers usually choose one of a few practical patterns.
Pattern 1: Render a link only when navigation is valid
Instead of disabling a link with CSS, render different HTML.
<nav>
<a href="/home">Home</a>
<span class="current-page" aria-current="page">About</span>
<a href="/contact">Contact</a>
</nav>
This is common in server-rendered apps and component-based frameworks.
Pattern 2: Keep the link and mark it as current
<a href="/about" aria-current="page" class="current-page">About</a>
This is useful when consistency matters and the team wants every nav item to remain a link.
Pattern 3: Guard behavior in JavaScript
document.addEventListener('click', event => {
const link = event.target.closest('a.current-page');
if (!link) return;
event.preventDefault();
});
This is an example of a guard clause:
- if the clicked element is not a matching link, return early
- otherwise stop navigation
Pattern 4: Component logic in frameworks
In React, Vue, Angular, or similar tools, developers often conditionally render either:
- a link component
- or plain text/current state markup
The idea is the same: do not rely on CSS alone for behavior.
Pattern 5: Accessibility-first navigation
A well-structured nav often uses:
aria-current="page"for the current page- visible styling for current state
- semantic HTML that matches intended behavior
Common Mistakes
1. Assuming CSS can truly disable a link
Broken expectation:
.current-page {
color: gray;
}
This only changes appearance. The link still navigates.
2. Using pointer-events: none as a complete solution
.current-page {
pointer-events: none;
}
This may block mouse clicks, but it does not fully replace proper semantics or behavior control.
How to avoid it:
- use it only when visual mouse blocking is enough
- prefer better HTML or JavaScript when behavior really matters
3. Using disabled on an anchor
Broken code:
<a href="/about" disabled>About</a>
disabled is not a valid disabling mechanism for standard anchor behavior.
How to avoid it:
- use a
<button>for button-like actions - use plain text or a
<span>for non-clickable current nav items
4. Removing href without considering meaning
<a class="current-page">About</a>
Without href, the element is no longer a normal navigable link. That may be fine, but be intentional about it.
How to avoid confusion:
- if it should not be a link, consider using
<span>or another appropriate element - if it should still be announced as the current page, use
aria-current
5. Disabling navigation when users still expect feedback
Sometimes preventing a click silently makes the interface feel broken.
How to avoid it:
- make the disabled/current state visually obvious
- consider adding a clear current-page style
- keep behavior consistent across the site
Comparisons
| Approach | Stops navigation? | Good for styling? | Semantic/accessible? | Best use |
|---|---|---|---|---|
| CSS color/text changes | No | Yes | No behavior change | Visual highlighting |
pointer-events: none | Usually for mouse clicks | Yes | Limited | Quick mouse-only blocking |
JavaScript preventDefault() | Yes | Can be combined with CSS | Better for behavior, but still not true disabled semantics | Blocking navigation intentionally |
| Remove/avoid the link in HTML | Yes | Yes | Usually best when item should not be clickable | Current-page nav item |
aria-current="page" | No | Can be styled | Yes, for current-page meaning | Accessible navigation state |
Link vs button
| Element | Use when | Supports disabled naturally? |
|---|---|---|
<a> | Navigating to another page or location | No |
<button> | Triggering an action in the current interface | Yes |
If the user is supposed to go somewhere, use a link.
If the user is supposed to perform an action, use a button.
Cheat Sheet
/* Visual-only styling */
.current-page {
color: gray;
text-decoration: none;
cursor: default;
}
/* Mouse click blocking */
.current-page {
pointer-events: none;
}
<!-- Current page kept as link -->
<a href="/about" class="current-page" aria-current="page">About</a>
<!-- Current page rendered as non-link -->
<span class="current-page" aria-current="page">About</span>
// Stop link navigation on click
document.querySelectorAll('.current-page').forEach(link => {
link.addEventListener('click', event => {
event.preventDefault();
});
});
Rules to remember
- CSS cannot truly disable a link semantically.
- A link's behavior comes from its
hrefand browser behavior. pointer-events: noneblocks pointer interaction, not meaning.disableddoes not work like you expect on normal<a>elements.- For a current page, the best solution is often to render plain text or use
aria-current="page". - Use
<button disabled>for disabled actions, not links.
Quick decision guide
- Want it to look inactive? Use CSS.
- Want to stop clicking with the mouse? Use
pointer-events: none. - Want to stop navigation behavior? Use JavaScript or change the HTML.
- Want the best current-page markup? Use
aria-current="page"and consider not rendering a clickable link.
FAQ
Can CSS completely disable an HTML link?
No. CSS can change appearance and can sometimes block pointer clicks, but it does not truly disable the link's semantic behavior.
Does pointer-events: none disable a link?
It prevents pointer interaction such as mouse clicks in many cases, but it is not a full disabled state.
Can I use the disabled attribute on an <a> tag?
Not as a standard way to disable navigation. Anchors do not support disabled like buttons do.
What is the best way to show the current page in navigation?
Use aria-current="page" and either keep the link styled as current or render the current item as non-clickable text.
Should I use a link or a button for disabled actions?
Use a button for actions and a link for navigation. Buttons support disabled; links do not.
Is JavaScript required to stop a link from navigating?
If the link still exists with an href and you want to block its behavior, JavaScript is the reliable way to prevent navigation on click.
Why not just leave the current page link clickable?
You can. Many sites do. But if you want a cleaner user experience, you may visually mark it as current or render it differently.
Mini Project
Description
Build a simple navigation menu where the current page is visibly highlighted and does not behave like a normal clickable link. This project demonstrates the difference between visual styling and semantic structure.
Goal
Create a small navigation bar that marks the current page clearly and uses appropriate HTML for clickable and non-clickable items.
Requirements
- Create a navigation menu with at least three items.
- Make one item represent the current page.
- Style the current page item differently from the others.
- Ensure the current page item does not navigate anywhere.
- Use accessible markup to identify the current page.
Keep learning
Related questions
Angular ngClass Conditional Class Binding Explained
Learn how to use Angular ngClass for conditional classes, fix common binding mistakes, and understand why this template error happens.
CSS :not() Selector for Elements Without a Class or Attribute
Learn how to use the CSS :not() selector to target elements that do not have a specific class or attribute, with examples and common pitfalls.
CSS Font Scaling Relative to Container Size: %, em, rem, vw, and Responsive Text
Learn how CSS font scaling really works and how to make text responsive using %, em, rem, vw, clamp(), and media queries.