How to disable a link semantically while maintaining accessibility?

Asked

Viewed 2,246 times

3

I noticed some elements like select, input and button has the attribute disable, but the element of link <a> does not seem to recognize this attribute and is not disabled.

Is there any way to make a disable in a link semantically?
I mean, is there any way to signal screen Readers (screen readers) that this link is disabled?

<button disabled>button disable</button>
<input type="submit" value="submit disable" disabled>
<select name="" id="" disabled>
    <option value="123">123</option>
    <option value="456">456</option>
</select>
<a href="#" disabled>link disable não funciona</a>

OBS: The intention is not to remove the link from the screen, is just signal that at the moment it is disabled.

  • 4

    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.

  • 1

    @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 attribute disable. The role of selectis 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...

  • 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?

  • @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

  • 1

    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 Pointer-Vent only disables the mouse, the element remains accessible by keyboard, giving Tab you can "click" the link

  • 1

    Yes, I say use Pointer-Vents to give the visual aspect, to disable the a would have to use Javascript.

  • 1

    @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

Show 3 more comments

3 answers

5

Exists on W3C that specifies a set of attributes to solve exactly the accessibility problems, called WAI_ARIA.

Basically you add an attribute called roles and implements a value:

<a href="#" role="button" aria-disabled="true">Section name</a>

Here are the supported commands in a link.

  • 1

    That is what semantics is all about. Thank you for your reply

2

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.

  • Thanks to the CSS-Tricks people

  • 1

    Thank you for your promptness and peace in translating the link https://css-tricks.com/how-to-disable-links/

1

I believe that disabling the redirect would be impossible, however, you can use some techniques to get around this situation. At first I imagined changing the class of your attribute <a> in the desired scenario for some specific stylization that blocks access to redirect, I did a search and found in this question the ONLY where I found something similar to what I imagined (using the property pointer-events: none;), I don’t know if the result actually behaves with what you want, but I found it quite appropriate with your situation.

The moment you wish to block the link, you could change the class of the element HTML for a class that disables the screen link, and vice versa.

Follow the example:

function ajustarLink(){
		var select = document.getElementById("select").value;
		
		if(select == "h"){
			document.getElementById("link").classList.add("habilitar");
		}else if(select == "d"){
			document.getElementById("link").classList.remove("habilitar");
		}
	}
.desabilitar {
  pointer-events: none;
}

.habilitar {
  pointer-events: auto;
}
<select name="" id="select" onchange="ajustarLink();">
	<option value=" "> </option>
    <option value="h">Habilitar link</option>
    <option value="d">Desabilitar dlink</option>
</select>

<a href="#" id="link" class="desabilitar" >link disable não funciona</a>

  • @hugocsl, that would be your situation?

  • 1

    From the point of view of enabling the link etc I am very cool, the response of the link tb is very interesting! Just missed the part of the semantics... But thank you for your contribution

Browser other questions tagged

You are not signed in. Login or sign up in order to post.