Anchors without href

Let’s say I’m building an app with buttons. These buttons don’t go anywhere and don’t do anything; they’re just used by the JavaScript to decide what to do next. (Assume that these buttons are added by the JS; if the user has JS disabled, something else entirely is presented.)

These links don’t go anywhere, so I don’t really need the href attribute. But I really want users to be able to tab to the buttons, if they’d like. I just read an article that suggests the following compromise:


<a href="javascript:void(0)"></a>

This is supposed to be better than setting href to “#” or some other placeholder value. I guess it’s mixing behavior and content, but that doesn’t bother me so much. What I’m really curious about is the accessibility. I assume an ideal solution would be for browsers to support tabindex=“-1”, but how is this “void” in the interim?

I don’t agree with the javascript:void in the href. Since you’re already practicing Good Coding by having Javascript create the buttons in the first place, you don’t have the issue of non-JS’d users trying to click buttons that don’t go anywhere.

This is supposed to be better than setting href to “#” or some other placeholder value. I guess it’s mixing behavior and content, but that doesn’t bother me so much.

Likely the article you read was pointing out that “#” as the href may force a page reload and bring the user back up to the top of the page, which you don’t want. But, YuriKolovsky taught me a nice trick: you can put a non-existent fragment in there and avoid all that.
<a href=“#void>Hahaha</a>
does nothing, but is focusable : )
<a href=”#foo">BAR</a>
If users are clicking on something else, and you want their focus to be brought to these elements, I do this (I do it for skip links as Safari and Chrome don’t necessarily bring user focus to unfocusable elements with the matching ID, just the visual focus):

<a href=“#somewhere”>This is a skip link to the part of the page called “Somewhere”</a>

later…
<a id=“somewhere” href=“#somewhere”>destination</a>
Here, additional clicking or accidental clicking to this element does not bring the user back up to the top of the page… they stay right there.

What I’m really curious about is the accessibility. I assume an ideal solution would be for browsers to support tabindex=“-1”, but how is this “void” in the interim?

You know, I’d have to test this (I can only test in JAWS though, I still have trouble navigating in Orca), but my assumption is the anchor just does whatever script you’re making the button do, and won’t go anywhere if you return false. Of course, if there is no anchor text, the reader may read out the “url” instead, which is not what you want. Titles may be read out instead, but you can turn those off in readers so there’s no guarantee the user will get the title instead of the url read out.

However if clicking the button does not move the focus, and you are just showing new content or something, then it’s possible the user does not become aware that there has been a change on the page.
If new content appears, you could use JS to move the focus from the button to the beginning of the new content (which, if it’s not focusable, could indeed have the negative tab index added to it with Javascript). You can also use ARIA attributes to let the user know something on the page has changed.

I wouldn’t use a non-focusable element for the buttons. Using negative tabindex is more for when you need to move keyboard focus to an element who is more semantically appropriate as a non-link.

You could take a look at this ARIA-friendly jQuery slider. You can see they’ve used a bunch of ARIA attributes (I don’t understand all of them yet).
http://www.filamentgroup.com/lab/update_jquery_ui_slider_from_a_select_element_now_with_aria_support/
A bit more with neg tabindex
http://dev.opera.com/articles/view/introduction-to-wai-aria/

What are these buttons doing, exactly? Is the user configuring the page?

If the user is making a bunch of choices on a page, without expecting to “go” anywhere, possibly a form with form controls makes more sense? There you also have focusable elements pre-ready for you.

Anyway if you have some kind of demo page you can link to, I can take a listen for you. I can even give Orca a try…Orca’s very different from JAWS, as it doesn’t have a virtual buffer.

1 Like

Dang. Thanks for the awesome response.

I don’t actually have anything at the moment like this. I read that article (Dear Javascript Guru: Please Stop Using The Hash Symbol For No-Op HREFs), and that got me thinking about the href attribute and the anchor element.

I guess my real question is this: What does the presence of an href say about an a? And what does its absence say? Should an anchor, ideally, only be used when you’re linking to a different page (or different part of the same page)? Is it wrong to use the anchor primarily to capture the tab?

1 Like

I guess my real question is this: What does the presence of an href say about an a? And what does its absence say? Should an anchor, ideally, only be used when you’re linking to a different page (or different part of the same page)? Is it wrong to use the anchor primarily to capture the tab?

I used to think the href was a requirement in the spec because some browsers didn’t react to anchors without one, but apparently it’s an optional attribute (!)
(you can see that it is not required by seeing that the specs call that attribute #IMPLIED (meaning the user agent might have it’s own default) and not #REQUIRED)
This possibility that some user agent may have a default is important… but you’re going to return false anyway right?

You’re thinking if there’s an href, the anchor is meant as a hyperlink to somewhere else, and if that’s not why you put it there, then maybe an anchor isn’t the right element?

I would say that in general hyperlinks should be used for going somewhere, whether it’s on-page or another page. However I have used them for when I need a focus point, mostly for accessibility reasons.
I’ve used them to make help text appear in forms.
I’ve used them to make something focusable in IE6 (who only focuses on anchors and inputs, and only does :hover and cursor:pointer on anchors).

However I’m careful to make sure the correct element (semantically) is also present: the anchor is usually WITH the correct element to help-along, and isn’t just scattered around for Doing Stuff. If I need to use anchors for that, they would be created purely in Javascript.

Again if these “tabs” you mean are for people to choose/select settings or that kind of thing, then a form of some sort may make way more sense. Forms can easily be kept accessible as they have pre-defined behaviours in user agents and modern screen readers are cool with those.

Re the article:
approach 1 as you’ve noticed leaves keyboarders out (unless you do the whole negative tab index thing… but look what they’re doing: taking a non-anchor and trying to make it an anchor. I find this worse than taking and anchor and making it a button).
Approach 2 seems silly: if I’m creating an anchor with Javascript in order to Do Stuff, then why am I adding Javascript inside to do nothing?
I’d even see if document.createElement(‘a’) with some textNode and an onclick event would work in all browsers (it might not, like IE8 might insist on an href). If it worked in all browsers then I’d consider making anchors-who-don’t-go-anywhere just not have that attribute.
However I’d also see if creating an actual <button> element was better. The point of <button> is to add scripts to it that Do Stuff… really the disadvantage of them is IE is retarded with them. There are Javascripts to fix that buggy behaviour though… Dean Edwards has one I believe.

Approach3 removes the flexibility of keeping event triggers external, you can’t use this and if you have a bazillion links on the page who need to do that same event, it’s a lot of added HTML crap. Even if you’re creating them in JS and adding them to the page… makework.

However the guy is absolutely right about the #. First place of trouble is the bringing the user to the top of the screen— this is especially a problem with users with a screen reader. They’ll know the page reloaded, and after they get the Title or start scrolling back into the page they’ll (hopefully) realise they’re on the same freakin page, and be like wtf? Instead, you want them to remain where they were.

Second issue with # is in menus like dropdown menus. People will have a Main category at the top, as an anchor with href=“#” and then use Javascript (or even JS and CSS) to make the dropdowns appear. This is retardation on a few levels: that top anchor should be an anchor, but instead of href=“#”, it should be href=“a page with all the same options available in the dropdown” because plenty of users won’t be able to get those dropdowns to show for one reason or another (no JS, or they’re using IE6 and you didn’t build for that, or they’re using a touch device that can’t :hover, or you didn’t make it keyboard-friendly…)

I surf with JS off 99% of the time. I notice these href=“#” and they bug me too. If the link doesn’t work without JS, remove it.

This defeats the guy’s main point though: IF you have href=“#” in an anchor who is created with Javascript in the first place, then you have an event on that sucker and you’re going to return false. So this behaviour of filling up your history (doesn’t on my browser but it’s a valid complaint) or bringing the user to the top isn’t an issue: even the “#” is false and gets ignored. Those without scripting who can’t run the event… don’t have any anchors anyway.

Still, I’d prefer to either
-try without href and see if that’s cross-browser
-use a non-existent href like #void or #foo
-see if another element like a <button> makes more sense (and if it works cross-browser… one button is usually ok but IE has issues with mutliple buttons and styling them or not letting text get cut off in them is IE trouble)

1 Like

Actually, I would suggest a slightly different thing. If the buttons only have the primary function of invoking JavaScript, perhaps not link to them as an anchor (as that directly implies that a resource is located at the end of the click event). Why not simulate the effect of a button (without it actually being one) by simply having an element styled with the usual text underlined (and hover colors etc) but with the onclick event in JavaScript attached to it (as regular text), that way when JavaScript is enabled, the “button” can be styled and made to resemble a link (you can even change the cursor to the pointer) yet if JS is disabled (it’ll look like ordinary text) and if a screen reader looks at it, it’ll just assume it’s regular text. If it’s not an anchor reference, no need to make it one! :slight_smile:

Would that not make it inaccessible to keyboard navigation, though? I thought in most browsers you could only tab to anchors and form controls.

if a screen reader looks at it, it’ll just assume it’s regular text.

The screen reader may be able to run the Javascript, if it can find it, so you might be unnecessarily reducing the functionality for screen reader users.

Good point, it would be helpful if we knew what the function actually did (what it’s being used for), I just suggested it as it would remove the issue (as I saw it). :slight_smile:

Alex: your suggestion is similar to #1 on the link the OP provided: the guy said, use a span and style it like an anchor. I don’t really like the smell of that one, but you could get around the non-focussing thing with a negative tabindex. I find an anchor’s default ability to be focussed safer than relying on tabindex though.

I probably missed it, or missed the reason not to, but why not simply set href=“”? The href makes the anchor focusable without linking to anything. It’s the practical equivalent to js void or return false, without all the js issues. And, it is keyboard addressable.

cheers,

gary

I probably missed it, or missed the reason not to, but why not simply set href=“”?

Same problem as href=“#”. Brings the user back to the top of the page. Counts as a refresh/new load. I remember someone didn’t let the anchor do anything with just “” but I can’t remember who (I’m thinking it was IE8, but that might have been the “no href at all” thing instead).

Though again, if they are created with JS and the JS is preventDefault or retrun false it shouldn’t be an issue.