[ACCEPTED]-Making links with no href accessible-wai

Accepted answer
Score: 10

To make a non-href <a> behave like an <a> (and 45 be accessible), you'd have to add role=link, tabindex=0, style 44 it to look like a real link, and add keyboard 43 handler code to treat Return as a click.

role="link" isn't 42 sufficient; a screenreader may report it 41 as a link, but without tabindex="0" and appropriate 40 visual styles, a sighted user won't be able 39 to tab to it in the first place, and without 38 a keyboard event handler, only mouse users 37 will be able to click it. (Technically screenreader 36 users typically have hotkeys to simulate 35 a mouse click, but keyboard-only sighted 34 users generally don't have that option, so 33 don't rely on it.)

Alternatively, if (big 32 if!) the crazy script you're using allows 31 for it, you could try shimming a 'keyboard 30 click source' (my terminology) <a> just inside 29 the original one: so where you have:

<a>foo</a>

you 28 replace it with:

<a><a class='shim' href="javascript:void(0)">foo</a></a>

(The class='shim' is only needed if 27 you need to do the event stuff described 26 later...) You can do this in jQuery using 25 something like: (borrowing from Jack's answer)

$("a:not([href])").wrapInner("<a class='shim' href='javascript:void(0)'></a>")

How 24 this works is that the inner newly-added 23 <a ...> has a href, so it is exposed as a link and 22 is tabbable. More importantly, if a user 21 tabs to it and presses return, the default 20 A behavior converts that keyboard input 19 into a click event. This specific A has a href that 18 returns undefined/void(0), so no actual 17 navigation happens, but the click event 16 will still bubble up to the original A, which 15 gets to act on it.

(This is a neat pattern 14 for allowing some parent element - often 13 a DIV or similar - to handle click events, adding 12 a child tabbable A that can source click 11 events from keyboard gives you UI that's 10 both mouse and keyboard usable.)

The big 9 caveat here is that it assumes that your 8 original script doesn't care about the target of 7 the event. If that script does check this, it 6 will get confused when it sees click events 5 coming from the shim A's rather than the 4 original As. One way to get around this 3 is to capture and re-raise the event, which 2 can be fiddly, and may only work on recent 1 browsers - eg using something like:

// 'shim' class used so we can do this:
$("a.shim").click(function(e) {
    e.preventDefault();
    e.stopPropagation();

    // the following works if listener using jQuery or is setting onclick directly, otherwise...
    // $(e.target).parent().click();.

    // More general way to raise events; may need alternate for IE<9
    var e2 = document.createEvent("UIEvents");
    e2.initUIEvent("click", true, true, window, 1);
    e.target.parentNode.dispatchEvent(e2)
});
Score: 2

Whilst it's not very pretty, you can get 9 at all anchors without a href attribute like 8 so, using jQuery;

$("a:not([href])")

You can then just set the 7 href attribute on those links to "#" and 6 that should make them work again as regular 5 links.

Here's a working JSFiddle

Sorry to reply with a jQuery solution...but 4 doing this in regular JavaScript would be 3 much more verbose.

Another way would be 2 to give the anchors a role and then select 1 them that way:

$("a[role='link']")

More Related questions