Use button if you mean it
Use <button>
if you want it to behave as a button.
If you are using any other HTML element
and updating its look, to look like button
, you are either bothering your users or yourself.
Why?
If you, want to fake any other HTML element
element as <button>
, you have to make sure the fake button
:
- is reachable via keyboard
- can be activated by pressing
enter
andspace
keys, i.e. invoke the click handler - is treated as
button
by assistive technologies, for example, screen reading software
For example, try it at sarbbottam.github.io/empower-your-users/button/accessible/
<button>Surprise me!</button>
and function clickHandler(e) { ... } button.addEventListener('click', clickHandler);
is sufficient to satisfy all the criteria.
To make a <span>
or <div>
or some other non-intractable HTML element
behave as button.
You have to
- add
tabindex=0
, to make it reachable via keyboard - listen to
keydown
event and detect ifenter
orspace
is pressed and invoke theclick
handler - use
role=button
so that it is treated asbutton
by assistive technologies, for example, screen reading software
Otherwise, it would result in a broken behavior, try it out at sarbbottam.github.io/empower-your-users/button/inaccessible
The markup would look something like
- <span>Surprise me!</span>
+ <span tabindex=0 role="button">Surprise me!</span>
And associated JavaScript
function clickHandler(e) { ... }
button.addEventListener('click', clickHandler);
+ span.addEventListener('keydown', function(e) {
+ if (e && (e.keyCode === 32 || e.keyCode === 13) ) {
+ // e.preventDefault();
+ // e.stopPropagation();
+ clickHandler(e);
+ }
+});
Why would you write so much extra code?
How about <a>
?
You still have to write few extra lines.
<a>
with out anhref
attribute is similar to<span>
,<div>
or some other non-intractableHTML element
<a>
withhref
attribute reacts toenter
keys but notspace
- So you have to listen to
keydown
event and detect ifspace
was pressed and invoke theclick
handler - Also you have to prevent the default behavior if
enter
key was pressed, other wise browser will navigate to the location, specified byhref
, even ifhref
is#
, other wise page will scroll up by default.
- So you have to listen to
- Have to add
role=button
so that it is read and treated asbutton
and notlink
by screen readers and assistive technologies
In Anchors vs Buttons, Ire Aderinokun explores different possibilities and suggests a hybrid approach of using <a>
and progressively enhancing it to a button
If Javascript is enabled, we can then change all the anchor elements to buttons.
I see the intent, of making the UI functional in non-JavaScript scenario, which is great.
The
<button type=“button”>
element, as mentioned, by default does nothing. JavaScript must be used to add functionality to it. Therefore, if the user doesn’t have JavaScript enabled on their device, then they can no longer access the content behind the interaction, in this case the navigation menu.
But I have a different opinion.
Purpose of buttons other than submit|reset
is coupled with JavaScript. Buttons other than submit|reset
, are of no use without JavaScript.
If you are relying on an interface, for non-JavaScript scenario, (which you should, as the base criteria),
design your interface accordingly, it should be simple.
For non-JavaScript UI, there should not be any notion of button
other than submit|reset
.
Let’s consider a scenario, inline edit of user’s profile information, it is not possible provide the functionality without JavaScript.
IMO, don’t display the inline edit option, for non-JavaScript UI, but display a link
which would navigate to an edit page.
If JavaScript is enabled, enhance the experience accordingly, progressively.
If you are still not encouraged to use <button>
, if you mean it, please read You can’t create a button by Nicholas C. Zakas
If you have enjoyed and feel benefitted from the post, please share it. Should you have different opinion, please share it via comments.
If you have enjoyed reading this post you can follow me on twitter @sarbbottam and learn about any new posts. Opinions expressed are solely my own and do not express the views or opinions of my employer.