The topic of disabling links appeared in my work the other day. Somehow, a "disabled" anchor style was added to our typography styles last year when I wasn’t looking. There is a problem: there is no real way to disable a link <a>
(with an attribute href
valid) in HTML. Not to mention, why would you want? Links are the foundation of the web.
At one point, it seemed that my co-workers would not accept this fact, so I started thinking about how this could be accomplished. Knowing that this would take a lot, I wanted to prove that it was not worth the effort and the code to support an unconventional interaction, but I feared that by showing it could be done, they would ignore all my warnings and use only my example. proof that everything was fine. This has not yet been too hectic for me, but I figured we could go through my research.
First thing:
Don’t do this.
A deactivated link is not a link, it’s just text. You need to rethink your design if it asks you to deactivate a link.
Bootstrap has examples of . disabled application for anchoring tags, and I hate them for it. At least they mention that the class only provides a disabled style, but this is misleading. You need to do more than just make a link look disabled if you really want to disable it.
Surefire Way (Beginner): Remove href
If you have decided that you will ignore my warning and continue with disabling a link, removing the href attribute is the best way to know how.
Directly from the official Hyperlink specification:
The href attribute in elements a and area is not required; when these elements do not have href attributes, they do not create hyperlinks.
An easier to understand definition of MDN:
This attribute can be omitted (as in HTML5) to create a placeholder link. A placeholder link resembles a traditional hyperlink, but leads nowhere.
Here is the basic Javascript code to define and remove the href attribute:
/*
* Use seu método preferido de segmentar um link
*
* document.getElementById('MyLink');
* document.querySelector('.link-class');
* document.querySelector('[href="https://url.net"]');
*/
// "Desabilitar" link removendo a propriedade href
link.href = '';
// Enable link by setting the href property
link.href = 'https://url.net';
Styling this via CSS is also quite simple:
a {
/* Estilo de links desabilitados */
}
a:link, a:visited { /* or a[href] */
/* Estilo de links habilitados */
}
That’s all you need to do!
That’s not enough, I want something more complex so I can look smarter!
If you simply need to do excessive engineering on some extreme solutions, here are a few things to consider. I hope you stay tuned and recognize that what I’m about to show isn’t worth the effort.
First, we need to style our link so it looks disabled.
.isDisabled {
color: currentColor;
cursor: not-allowed;
opacity: 0.5;
text-decoration: none;
}
<a class="isDisabled" href="https://url.net">Link desabilitado</a>
Set the color as currentColor
should reset the font color back to its normal text color without link. I am also setting the mouse cursor to not-allowed
to display a good indicator in focus that normal action is not allowed. We have already left out users who are not mouse and can not pass the mouse, especially touch and keyboard, so they do not receive this indication. Then the opacity is cut in half. According to WCAG, deactivated elements do not need to meet the color contrast guidelines. I think this is very risky since it’s basically plain text right now, and halving opacity would make it very difficult for users with low vision to read, another reason why I hate it. Finally, the underscore of the text decoration is removed, as this is usually the best indicator that something is a link. Now this looks like a link disabled!
.isDisabled {
...
pointer-events: none;
}
Ok, we’re ready! Link disabled completed! Except, it’s only actually disabled for mouse users by clicking and tapping users by tapping. What about the browsers that do not support point-events
? According to kennel, This is not supported for Opera Mini and IE <11. IE11 and Edge do not actually support pointer events unless the display is set to block
or inline-block
. Also, set up pointer-events
for none
overwrites our nice cursor not allowed, so that now mouse users won’t get that additional visual indication that the link is disabled. This is already starting to fall apart. Now we have to change our markup and CSS ...
.isDisabled {
cursor: not-allowed;
opacity: 0.5;
}
.isDisabled > a {
color: currentColor;
display: inline-block; /* IE11/ MS Edge bug */
pointer-events: none;
text-decoration: none;
}
<span class="isDisabled"><a href="https://url.net">Link desabilitado</a></span>
Wrap the link in a <span>
and add the class isDisabled
gives us half our visual style disabled. A good side effect here is that the disabled class is now generic and can be used on other elements such as buttons and form elements. The royal anchor mark now has the point-events
and the text-decoration
defined as none
.
What about keyboard users? Keyboard users will use the key ENTER
to activate the links. The points-events
are only for pointers, there are no keyboard events. We also need to prevent the activation of older browsers that do not support points-events
. Now we have to introduce some Javascript.
For Javascript.
// After using the preferred method to direct the link
link.addeventlistener('click', Function (Event) {
if (this.parentElement.classList.contains('isDisabled')) {
Event.preventDefault();
}
});
Now our link seems disabled and does not respond to activation through clicks, keystrokes and key ENTER
. But we’re not finished yet! Screen reader users have no way of knowing that this link is disabled. We need to describe this link as being disabled. The attribute disabled
is not valid on links, but we can use aria-disabled = "true"
.
<span class="isDisabled"><a href="https://url.net" aria-disabled="true">Link desabilitado</a></span>
Now I will take this opportunity to style the link based on the attribute aria-disabled
. I like to use ARIA attributes as hooks for CSS, because having elements with inappropriate styles is an indicator that important accessibility is missing.
.isDisabled {
cursor: not-allowed;
opacity: 0.5;
}
a[aria-disabled="true"] {
color: currentColor;
display: inline-block; /* IE11/ MS Edge bug */
pointer-events: none;
text-decoration: none;
}
Now our links seem disabled, disabled and are described as disabled.
Unfortunately, even if the link is described as disabled, some screen readers (JAWS) will still announce it as clickable. It does this for any element that has a click listener. This is due to the developer’s tendency to create non-interactive elements like div
and span
as pseudo-interactive elements with a simple listener. Nothing we can do about it here. Everything we did to remove any indication that this is a link is frustrated by the assistive technology that we were trying to fool, ironically, because we tried to fool you before.
But what if we change the listener to the body (body
)?
document.body.addEventListener('click', function (event) {
// filter out clicks on any other elements
if (event.target.nodeName == 'A' && event.target.getAttribute('aria-disabled') == 'true') {
event.preventDefault();
}
});
Did we break up? Well, not really. At some point, we need to enable these links, so we need to add additional code to toggle this state / behavior (state/behavior).
function disableLink(link) {
// 1. Adiciona a classe isDisabled class ao span pai
link.parentElement.classList.add('isDisabled');
// 2. Armazenar href para que possamos adicioná-lo depois
link.setAttribute('data-href', link.href);
// 3. Remove o href
link.href = '';
// 4. Define aria-disabled para 'true'
link.setAttribute('aria-disabled', 'true');
}
function enableLink(link) {
// 1. Remove classe 'isDisabled' do span pai
link.parentElement.classList.remove('isDisabled');
// 2. Seta href
link.href = link.getAttribute('data-href');
// 3. Remove 'aria-disabled', melhor do que definir como falso
link.removeAttribute('aria-disabled');
}
That’s it. Now we have a disabled link that is visual, functional and semantically disabled for all users. Only 10 lines of CSS, 15 lines of Javascript (including 1 body Listener) and 2 HTML elements were required.
I may be wrong... I don’t see a semantic solution to disable a link... his role in hypertext is to direct the reader to a point... if it doesn’t exist or is unavailable, it is not his competence. Your presentation and behavior can be changed to indicate this to the user and improve your experience, but so seems to me an aesthetic solution and not semantic.
– Leandro Angelo
@Leandroangelo the
<select>
is another element, which more than the button or input, visually and intrinsically suggests that the user interacts with it http://prntscr.com/mn63i5, but just like the others also has the attributedisable
. The role ofselect
is to select some option, but can be disabled... The intention is precisely to show visually and tb to the screen readers that the link is disabled. Just like the other elements. I believe that W3C / WCAG offers some solution to treat this...– hugocsl
Hello @hugocsl, you want to take a disable on the link, but do not want to remove the link from the screen. I don’t quite understand this case, but in my view I believe that what you want is to disable redirect by clicking, this is it?
– RXSD
@Andréfilipe want to keep the link on the screen, but treated in a way that is disabled, IE, that does not work until it is enabled, as for example the select or button, that are visually, functionally, and semantically "disabled"... BS itself appears to have a similar feature https://bit.ly/2XauxOu
– hugocsl
I was preparing a response using Pointer-Events of the CSS, but you already have a question similar to yours and very good answers here: https://answall.com/questions/2352/como-impedirum-click-sobre-um-link-%C3%A2ncora-ou-elemento-com-evento-amarrao and here https://answall.com/questions/251381/pra-que-serva-propriedade-Pointer-Events
– LeAndrade
@Leandrade Pointer-Vent only disables the mouse, the element remains accessible by keyboard, giving Tab you can "click" the link
– hugocsl
Yes, I say use Pointer-Vents to give the visual aspect, to disable the
a
would have to use Javascript.– LeAndrade
@Leandrade yes, but not only disable/enable, the point is how to treat it semantically with the accessibility attributes that we can use in the element. But thanks for the intention to help :) and thanks for the links
– hugocsl