Javascript Triggers using <a>
For several recent projects, I've seen increased requests for a hidden div of content to be revealed when someone clicks a link.
For example, in Basecamp, if you want to write a message, you can just start typing in the textarea. Alternatively, if you want your text to have some formatting, a formatting guide will appear if you click a certain link.

Clicking the link triggers a javascript function that reveals the formatting guide.

A link toggler to trigger a hidden div is a very common approach for the show/hide effect. An <a> tag will have an href of "#" and an onclick event handles the toggling of an action, such as displaying a previously hidden div that, by default, was set to style="display:none;".
The largest advantage of the trigger text being a link is that users know that links are clickable, like tabs and buttons. If that trigger is to exist within the flow of paragraph text, then links (as opposed to tabs or buttons) is the way to go.
I've begun to question whether this trigger should be a link at all (meaning using the <a> tag) rather than <span>, and I was curious if anyone else has questioned this as well. I considered the thought, "Shouldn't links always be used to take the user somewhere?" Coincidentally, 37signals, who makes Basecamp, had a post about the show/hide links, in which they mention the "different breed of hyperlink—the 'do something' link, rather than the 'go somewhere' link."
If the user isn't going to be taken anywhere, is using the <a> element the best tag to use? Instead of continuing the "different breed" of hyperlink, use the <span> element instead, styled to look like a link.
HTML
<p>
Check the
<span class="actionlink" onclick="toggle('specialstuff')">
formatting guide
</span>
...
</p>
CSS
span.actionlink {
color:#039;
text-decoration:underline;
cursor:pointer;
}
// and for browsers that support hover, the following:
span.actionlink:hover {
text-decoration:none;
}
In this manner, a span of text can be the trigger, still look clickable to the end user, and there is no need to use <a> for text that doesn't really take the user anywhere.
Then again...
In thinking this through, another approach dawned on me that is even more standards-friendly.
If you are an accessibility zealot, you've probably already noticed something that should be different in the above examples: no div should have style="display:none;" declared in the markup. If javascript were not enabled in a user's browser, the user would not have the option to trigger an event to change that style to display:block. That div may have helpful content, but it wouldn't be accessible - it'd be in a state of purgatory, like being buried alive, forever ignored. If that div were a character in Law and Order, it would be the neglected teen that committed the murder because he was starved for attention from Daddy, but Mommy doesn't want to look like a bad mom so she insists that she, not her son, did the crime.
...
Instead, the div could just have an id, and javascript could be used to set that div with display:none; on page load.
For instance, instead of this...
<div style="display:none;" id="specialstuff">
...
</div>
Use this...
<div id="specialstuff">
...
</div>
and a style for #specialstuff to have display:none could be set via javaascript.
Then, in our original trigger link, instead of having a throw-away href...
<p>
Check the
<a href="#" onclick="toggle('specialstuff')">
formatting guide
</a>
...
</p>
Put in something actually useful - a link to the anchored element - making our link an actual "go somewhere" link in addition to a "do something" link.
onclick="toggle('specialstuff')">
formatting guide
</a>
...
</p>
The idea being, if javascript were disabled, the trigger element still has value in that clicking it will take the user to the desired div. If javascript is enabled, the script could ignore the href and just trigger the show/hide behavior.
Comments (7)
JD said:
Nice semantic approach. I would add that thinking through your markup, no matter what level of programmer you are, is an important practice. Often designers just throw their tags around to make the page render the way they want it to – without considering what their markup really means.
# February 28, 2007 5:55 PM
Devon Young said:
Yahoo's front page does it like that for the little tab box. If you have JavaScript off, it'll still take you to the content. It only uses JavaScript and CSS to make it work in a more user friendly sense. I assumed everybody was doing it that way by now because it's the only way that makes any sense. Since they're not, it's awesome you've made this little tutorial for it. Maybe it'll become more widespread. :)
# February 28, 2007 9:55 PM
William said:
The href="#" causes the browser to scroll back to the top, which is a very jarring experience. What's wrong with just using <a onclick=""></a>?
# March 1, 2007 11:45 AM
William said:
I understand that your approach of having it scroll to the div partly gets around my complaint that just using href="#" causes the page to scroll annoyingly to the top, but this seems like a similarly annoying behavior. It deals with potential lack of javascript issue (which is irrelevant to my enterprise application, but obviously not to the general public) but produces annoying behavior for everyone who does have javascript.
# March 1, 2007 11:55 AM
CSS Guy said:
@William:
If "return false;" is included in the javascript (and in the instances where I've seen the effect, "return false" is usually included), the jump to the top, or jump to the anchor, that you described wouldn't occur. So people with javascript are spared from that effect.
If you didn't have javascript enabled, then you would want to send the user to a certain destination.
There is nothing "wrong" with having onclick in the <a> tag. But to keep behavior separated from markup (which keeps in line with web standards), the onclick event would preferably be added on page load by javascript, rather than be hard-coded into the markup.
# March 1, 2007 12:31 PM
Daniel said:
This is great and I'm glad you took the time to consider users who do not have javascript enabled. In response to what William said:
I personally always like to have something in the href, even just a hash symbol. To avoid being returned to the top of the page after clicking the link w/ href = "#" (and since the user is only clicking the link to trigger some javascript we can assume that they have javascript enabled) you need to pass the event into the function you trigger as a parameter and in the function called disable the events default behavior.
ex:
<a href = "#" onclick= "foo(event);">HI</a>
function foo(ev){
ev.preventDefault();
//do other stuff
}
I hope that helps someone as much as it has helped me.
# March 6, 2007 2:24 PM
mark rush said:
http://i have found a much better way of doing this without the need for inline javascript and have put it to good use on sites like www.nemarkmedia.co.uk as a way of actioning the rollover images again without inline javascript!!! see my blog for details!
# March 27, 2007 5:16 PM