The basics are this (with notes added by me):

- you get automatic semantics and accessibility using the right element for the job.
- if you don't (and use something like a div or span for a button) you need to manually add in all the accessibility and functionality yourself.

- links are clicked and activated with ENTER or single tap. They take you somewhere.

- buttons are clicked and activated with SPACEBAR or ENTER or often double-tap (this is why single taps on buttons are sometimes slow... browser is waiting to see if the tap is really a double tap. You can get around this by using touchEnd events instead of click events for your mobile pages). They usually Do Stuff rather than take you somewhere.

I'm guilty of using links to Do Stuff, quite regularly.

<a class="btn"></a>
If an anchor doesn't have an href attribute, it may not be focusable (I know addThis twitter buttons didn't work in any version of IE I tested in with keyboard, solely due to lack of href). AT doesn't see anything focusable or clickable there either. It does not exist as far as they're concerned.

<a href="#"></a>
If an anchor is empty and you're using a background image to show the clickable thing and its text, this can and will vanish when users have High-Contrast settings in their browser (Microsoft has a possible CSS option for reversed icons here and I only know of the High-Contrast issue on Windows but if images vanish anywhere else then this also can't be a complete solution).

The above link will also take users to the top of the page. Disturbing someone's focus even if visually nothing changes is a pain in the butt.

-------------------------MOAR NOTES---------------------------------
I've been using a non-existing hash for these: <a href="#void">link focus goes nowhere when clicked</a>. Still, I should be using a <button>.

If you're forced to deal with spans or divs as buttons, like trying to fix someone's jQuery plugin, you need to do *at least* all this:

<span role="button" tabindex="0">FAKE BUTTON</span>
Role of button gives it a role to browsers and AT. Tabindex makes it natively focusable without screwing with native tab order (don't set to a number larger than 1). Even so, now you can focus on it but can't activate it.

In your Javascript onclick method you need to add an onkeyup or onkeypress or whatever your favourite is and test for ENTER and SPACEBAR.
Here's a chunk I did for a jQuery plugin our company uses but by default only works with the mouse:
var resetbtn = item.find('.rateit-reset');
    if (stuff is true...) { () {
            //does stuff onClick;

    //is role=button, but not natively clickable
        resetbtn.keyup(function(e) {
            var code = e.which;
            if ((code === 13) || (code === 32)) {