Whether a link should be used or not carries more semantical than presentational value. It should not be disabled through CSS, but through utilizing the hidden attribute that is applicable to any HTML element. CSS then can be used to select e.g.a[hidden] anchor and style it accordingly.
– amnJul 11 '16 at 12:22

@amn but i don't think browsers will display an element with the hidden attribute so styling becomes moot.
– user1794469Jan 11 '17 at 15:59

1

@user1794469 They will if you instruct them to, with CSS, using display: block, for instance or some other value for display. But hidden is not always applicable -- it's for elements that are irrelevant, and from the question it is not unclear why the link should be disabled. This is probably a case of XY problem.
– amnJan 19 '17 at 13:05

Also, this doesnt avoid tabbing to the link then enter.
– JonoDec 22 '13 at 9:26

3

If you would style it a bit, so the user can see it's disabled. Give it some opacity: .2
– DNRNFeb 4 '14 at 10:13

3

This now works in all modern browsers including IE 11. If you need support for IE 10 and below, you can use a JavaScript polyfill such as this one.
– KeavonJul 31 '14 at 5:13

24

Important note: This only disables clicking, not the actual link itself. You can still use tab + enter to "click" the link.
– Pikamander2Sep 23 '14 at 23:55

9

Use of pointer-events: none; is not perfect. It also disables other events such as hover, which is required for display of title="…" or tooltips. I found the JS solution is better (using event.preventDefault();) along with some CSS (cursor: default; opacity: 0.4;) and a tooltip explaining why the link is disabled.
– Quinn ComendantJul 24 '15 at 3:34

For style, try changing pointer-events:none; to pointer-events:unset;. Then, the cursor can be changed to cursor:not-allowed;. This gives a better clue as to what is going on to the user. Seems to work in FF, Edge, Chrome, Opera and Brave as of today.
– SablefosteSep 5 '17 at 1:17

@Sablefoste That doesn't work for me in Chrome 60. The cursor is indeed not-allowed, but the link remains clickable.
– soupdogSep 11 '17 at 20:19

Use JavaScript, to find the anchor elements with that class, and remove their href or onclick attributes accordingly. jQuery would help you with that (NickF showed how to do something similar but better).

The pointer-events property allows for control over how HTML elements
respond to mouse/touch events – including CSS hover/active states,
click/tap events in Javascript, and whether or not the cursor is
visible.

That's not the only way you disable a Link, but a good CSS way which work in IE10+ and all new browsers:

Thanks to everyone that posted solutions, I combined multiple approaches to provide some more advanced disabled functionality. Here is a gist, and the code is below.

This provides for multiple levels of defense so that Anchors marked as disable actually behave as such.
Using this approach, you get an anchor that you cannot:
- click
- tab to and hit return
- tabbing to it will move focus to the next focusable element
- it is aware if the anchor is subsequently enabled
1. Include this css, as it is the first line of defense. This assumes the selector you use is 'a.disabled'
a.disabled {
pointer-events: none;
cursor: default;
}
2. Next, instantiate this class such as (with optional selector):
$ ->
new AnchorDisabler()

Here is the coffescript class:

class AnchorDisabler
constructor: (selector = 'a.disabled') ->
$(selector).click(@onClick).keyup(@onKeyup).focus(@onFocus)
isStillDisabled: (ev) =>
### since disabled can be a class or an attribute, and it can be dynamically removed, always recheck on a watched event ###
target = $(ev.target)
return true if target.hasClass('disabled')
return true if target.attr('disabled') is 'disabled'
return false
onFocus: (ev) =>
### if an attempt is made to focus on a disabled element, just move it along to the next focusable one. ###
return unless @isStillDisabled(ev)
focusables = $(':focusable')
return unless focusables
current = focusables.index(ev.target)
next = (if focusables.eq(current + 1).length then focusables.eq(current + 1) else focusables.eq(0))
next.focus() if next
onClick: (ev) =>
# disabled could be dynamically removed
return unless @isStillDisabled(ev)
ev.preventDefault()
return false
onKeyup: (ev) =>
# 13 is the js key code for Enter, we are only interested in disabling that so get out fast
code = ev.keyCode or ev.which
return unless code is 13
# disabled could be dynamically removed
return unless @isStillDisabled(ev)
ev.preventDefault()
return false

Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).