A young woman's torso and navel

Web developers will often use <button> elements interchangeably with or <div> and <span> tags styled to look like buttons, but the reality is that each element has its own specialized function and role.

While there are always exceptions, current best practices could be defined as:

  1. When linking to another resource, use an <a> link. Links to pages, download files, anchors etc. should always be real links. You can style those links to appear however you wish.
  2. If a UI element takes an action on the same page, it should usually be a <button>. Clicking on the button will usually modify the page, rather than jumping to a completely new resource: a print button, for example.
  3. Reserve other techniques, such as <span> tags styled to look like buttons, for edge cases.

Why use a <button> element?

  • Much easier to style than <input type=button>.
  • Designed as a UI element (unlike <div> and <span>) with better semantics, events and
  • Can contain other HTML elements, such as <span> or <img>, and pseudo-elements.

Now we know the reasons why <button> should be used, let’s look at how.

The Original Button: Form Roles

You’re almost certainly familiar with <input type=submit>:

<form action="destination.php">
	<input type=submit>
</form>

But this will also work:

<form action="destination.php">
	<button>Go!</button>
</form>

In other words, the default type attribute of <button> is submit. If you use a <button>, it’s important that you make it clear that the element does not submit a form:

<button type=button>Generic Button</button>

This is now functionally equivalent to:

<input type=button value="Generic button">

You could use either type anywhere on a HTML5 page, although my preference is to use the <button> element for UI, reserving <input type=button> for forms.

If A Button Uses JavaScript, It Should Be Added To The Page With JavaScript

The most frequent use of the <button> element is to initiate some JavaScript. You’ll frequently see this written on an HTML page:

<button type="button" onclick="funkalicious">Get Funky</button>

Ignoring for the moment the fact that this employs an inline event, there is a larger problem: we’re assuming that the browser has JavaScript running. This is a small but significant risk: it’s far better to add the button to the page using JavaScript in the first place:

var funky = document.createElement("button");
funky.type = "button";
funky.innerHTML = "Get Funky";
var mood = document.getElementById("mood-setting");
mood.appendChild(funky);

This is a much better approach: the button won’t be added to the mood-setting element unless JavaScript is already running in the browser.

Avoid Inline Events

Returning to our earlier example:

<button type=button onclick=funkalicious>Get Funky</button>

As a general rule, we should avoid inline JavaScript for the same reason that we avoid inline styles: they’re difficult to track and change. Assuming we’re using modern browsers, a better approach is to simplify the button: <button type=button id=funky>Get Funky</button>

Then, move the event inside a listener, in an external script:

funky.addEventListener('click', function() { funkalicious(); });

This abstracts the script away from the button, making it far easier to maintain.

When Appropriate, Add a title

title can be used to enhance a button:

<button type=button id=funky title="Change the music track">Get Funky</button>

This explanation will appear as a tooltip when the user hovers over the element; text-to-speech devices will read it out loud.

Alter States With Consideration

When tabbed to, buttons will have an outline applied, with another style applied momentarily as the mouse is held down on the element. As accessibility considerations, these should be altered with great reluctance: if you do change a state, ensure that the button remains visibly different in that state.

A button element without padding zoomed in Chrome

Other CSS? Go Wild

As you’ll see in tomorrow’s article, it’s very possible to use CSS to transform the appearance of a <button> element completely: they don’t have to be gray capsules on a page. At a basic level, I would provide padding for the element, otherwise Chrome will tend to scale it strangely as the page is zoomed in:

button { padding: .3rem; }

Photograph by Max Charping, used under a Creative Commons Generic Attribution 2.0 license

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.