0

Most of user interaction elements associated to a custom JavaScript behavior in Web applications can be HTML links (a elements) having a meaningful href attribute value, enabling them to be used in non JavaScript-enabled environments:

<a id="profile" href="profile">Profile</a>
<script>
  document.getElementById("profile").onclick = function() {
    return !open(this.href, "_blank", "scrollbars=no,status=no"); // whatever
  };
</script>

But some interaction elements are deeply linked to JavaScript, either because the Web application they are contained in requires JavaScript to run or because they were generated by JavaScript and don't make any sense when it is not available.

For those, as I want users to be able to interact with them whatever device they are on (i.e. I don't want to define mouse, keyboard, touch, … interaction by myself on a span element), I see two relevant HTML elements: a and button.

My problem with the a element here is that it defines at least one behavior I don't want: the ability for the user to open its target anywhere he wants to (e.g. in a new tab), whereas the interaction I want to take place is specific to the current tab.

My problem with the button element here is that, as far as I can tell from the online resources, it is difficult to style reliably on all modern browsers (but I am not sure if it is still the case now).

Some of the facets of this question have already been answered elsewhere, but I can't find a comprehensive and up-to-date summary: what HTML element would you recommend to use?

Julien Royer
  • 1,419
  • 1
  • 14
  • 27

1 Answers1

3

If you want an element to semantically be a button without the style issues of a <button> element, or behavior of an <a href> element, then you should use an element with [role="button"]. <span> is commonly used, but pretty much any element could be used.

<span role="button"></span>

Now, [role="button"] is really just a flag for assistive technology, so some interactions need to be set up to react as a button, but they're actually quite easy.

Buttons (such as links and form elements) are typically tabbable. This isn't always necessary, such as if a keyboard shortcut has been set for it already. If you want the <span> in the tabbing order, just add the [tabindex] attribute:

<span role="button" tabindex="0"></span>

Now you can tab to the button, but you'd probably still want to trigger the click event when Enter and/or Space is pressed.

Simply adding an event listener to the button is enough.

For brevity this example uses jQuery:
$(document).on('keydown', 'span[role="button"]', function (e) {
    if (e.which === 13 || e.which === 32) {
        $(this).click();
        e.preventDefault();
    }
});

This uses an event delegation format to provide click support for all spans with [role="button"], you may want to choose a different selector depending on your situation.

Now all that's left is to listen for when the button is clicked:

Again, jQuery:
$('.myButtonClass').click(function () {
    ...do stuff...
});

Now, for other devices, you're going to want to trigger a click on, say, a touch event. If you're using jQuery, there are assorted libraries to support turning touch into click and/or tap. If you're not using jQuery, it's not a lot of work to listen for touch events.

I'm not going to provide a code example to handle touch, but that's because it depends on what the button is supposed to do. In some cases you want to trigger a handler simply by starting a touch on the button (equivalent to mousedown), in other cases you want to trigger the handler if you've started and stopped the touch event on the same element (similar to how click works normally).

zzzzBov
  • 174,988
  • 54
  • 320
  • 367
  • Browser support for the `[role]` attribute is hit and miss, but fortunately browsers that don't support it don't do anything with it, so there's no risk in using it. – zzzzBov Nov 16 '12 at 15:08
  • Thank you for this very comprehensive answer; the only thing I don't like about it is the "from scratch" approach: it means adding the whole behavior a `button` is supposed to have without being sure nothing has been forgotten (I wouldn't like to test all screen readers); what about behaviors added in future browser versions? I get from your answer that `button`s are still painful to style? – Julien Royer Nov 16 '12 at 15:15
  • @JulienRoyer, ` – zzzzBov Nov 16 '12 at 15:20