A Bit on Buttons

Avatar of Chris Coyier
Chris Coyier on


The other day we published an article with a bonafide CSS trick where an element with a double border could look like a pause icon, and morph nicely into a CSS triangle looking like a play icon. It was originally published with a <div> being the demo element, which was a total accessibility flub on our part, as something intended to be interacted with like this is really a <button>.

It also included a demo using the checkbox hack to toggle the state of the button. That changes the keyboard interaction from a “return” click to a “space bar” toggle, but more importantly should have had a :focus state to indicate the button (actually a label) was interactive at all.

Both have been fixed.


Adam Silver has an interesting post where the title does a good job of setting up the issue:

But sometimes links look like buttons (and buttons look like links)

Buttons that are buttons aren’t contentious (e.g. a form submit button). Links that are links aren’t contentious. The trouble comes in when we cross the streams.

Buttons (that have type=”button”) are not submit buttons. Buttons are used to create features that rely on Javascript. Behaviours such as revealing a menu or showing a date picker.

A call-to-action “button” is his good example on the other side. They are often just links that are styled like a button for prominence. This whole passage is important:

In Resilient Web Design Jeremy Keith discusses the idea of material honesty. He says that “one material should not be used as a substitute for another, otherwise the end result is deceptive”.

Making a link look like a button is materially dishonest. It tells users that links and buttons are the same when they’re not.

In Buttons In Design Systems Nathan Curtis says that we should distinguish links from buttons because “button behaviours bring a whole host of distinct considerations from your simple anchor tag”.

For example, we can open a link in a new tab, copy the address or bookmark it for later. All of which we can’t do with buttons.

Call to action buttons— which again, are just links — are deceptive. Users are blissfully unaware because this styling removes their natural affordance, obscuring their behaviour.

We could make call to action buttons look like regular links. But this makes them visually weak which negates their prominence. Hence the problem.

I find even amongst <button>s you can have issues, since what those buttons do are often quite different. For example, the Fork button on CodePen takes you to a brand new page with a new copy of a Pen, which feels a bit like clicking a link. But it’s not a link, which means it behaves differently and requires explanation.


I’ll repeat Adam again here:

Buttons are used to create features that rely on Javascript.

Buttons within a <form> have functionality without JavaScript, but that is the only place.

Meaning, a <button> is entirely useless in HTML unless JavaScript is successfully downloaded and executed.

Taken to an extreme logical conclusion, you should never use a <button> (or type="button") in HTML outside of a form. Since JavaScript is required for the button to do anything, you should inject the button into place with JavaScript once it’s functionality is already ready to go.

Or if that’s not possible…

<button disabled title="This button will become functional once JavaScript is downloaded and executed">
  Do Thing

Then change those attributes once ready.