Web developers will often use <button>
elements interchangeably with <a>
links 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:
- 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. - 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. - 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 accessibility - 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.
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.