Article

The importance of <button>

Nick Krantz

May 20, 2021

It’s possible to use different elements to create buttons that look the same to the user, but should you?

Front-end frameworks have simplified the process of adding event listeners to any HTML element, including listeners for click events. React/JSX has onClick, Angular has (click) and Vue has v-on:click. The ease of use of these built in functions is miles better than manually attaching event listeners using JavaScript but can attract the bad practice of creating buttons using any element. Buttons should be <button> tags, for ease of development, accessibility and to the benefit of the end user.

Keyboard Navigation

When a user tabs through a web page, the browser moves through the page from one focusable element to the next. Only a handful of elements natively receive focus from the keyboard and luckily <button> is one of those elements! Using something other than a button would result in having to set tabIndex=0 for that element and add CSS :focus selector so the user is visually informed of the focused element.

Toggling focus state for a button element, only the button element natively receives focus

A user doesn’t have to use their mouse or trackpad to interact with a button: the spacebar or the enter key will trigger a click event in modern browsers. With any other element, a developer would have to add a keypress listener and then determine if the correct key is pressed.

Screen Readers

For a fully accessible web, screen readers are essential, moving through the DOM speaking aloud the content on the page. In the case of a button, a screen reader would say: “Click me, button”. Telling the user that they are focused on a button and can interact with it.

Using other elements can result in differing experiences, for example a <div> used as a button will only read the text content and not describe the element. Other elements have a range of experiences with a screen reader but if used as a button the user could end up not knowing they are on an element they could interact with.

Button Attributes

There are a handful of attributes that are natively supported for <button>, and a major one that I wanted to focus on is disabled.

Disabling a button and applying a set of styles is a common scenario for a developer and an end user. Indicating to a user that they need to complete some other prerequisites for some functionality and giving the developer some safeguard that those prerequisites are complete if the click event of the button are triggered.

When the disabled attribute is set, the browser doesn’t trigger a click event, from either a mouse or keyboard interaction. This saves the developer from implementing a check in their event handler to see if the button is disabled with some other method.

Styling

Browsers & operating systems apply default styles to buttons, that could incline a developer to choose a non-button element to start with a blank slate. These styles from the browser vary from browser to browser, but background-color, border, border-radius, padding and margin are a common few that browsers tend to set. To clear any operating system based theming, set the CSS appearance property to none. Depending on your design and desired browser support there could be more properties that need attention other than those already described. Normalizing CSS across the browsers is a small cost added to design related work that a developer is probably already doing but with all of the upside that comes with <button>.

Just use <button>

You could create the equivalent of a functional and accessible button element by adding a tabIndex, :focus styles, click and keypress listeners, role="button", and a disabling mechanism.

Or you could just use <button>.



Nick works at Livefront , where buttons are designed so well you almost have to click them.