Button, Link, or Neither? Three Principles for Clarity and Accessibility
- 5 minutes read - 929 wordsWhich HTML elements should we be giving a user to click? In this post, I’ll share some best practices for clickable elements.
To summarize:
- Most clickable elements should be links or buttons.
- Use buttons and links for their respective jobs.
- Clickable elements need signifiers.
Let’s get into it!
Most Clickable Elements Should Be Links or Buttons
Peruse a website’s markup;, and you’ll find many clickable elements that look
like an HTML button
, but aren’t: div
, span
, tr
, etc. Sometimes there are no
actual buttons in an application at all!
If this post convinces you of anything, let it be this: most clickable things should be links or buttons. You have to make a case to do otherwise. We can bend more things than we think into one of these elements. Using links or buttons makes the document better because it will tend to be more semantic and accessible.
Let’s look at each of those terms.
Semantic
Semanticism is a goal in user interfaces of using tags that have meaning.
When you use a link or button element, you’re writing markup that has meaning.
Those elements mean something independent of the medium. Your intent will be
better understood by every consumer than general tags like div
.
The React docs on accessibility make this case:
“Semantic HTML is the foundation of accessibility in a web application. Using the various HTML elements to reinforce the meaning of information in our websites will often give us accessibility for free.”
Not every tag can be semantic, but most can, and should be.
Accessibility
Links and buttons are more accessible than generic tags.
Assistive technologies are getting smart these days: give a div
a click
handler or even a class with the substring ‘btn’ in it, and some screen readers
decide that it’s clickable. But why take that chance, when there’s an
accessible alternative readily at hand?
Use Buttons and Links For Their Respective Jobs
Buttons and links do different things. Use the right one in the situation you’re in.
Here’s a useful but imperfect mental model: buttons “do something” and links “go somewhere.” This is getting blurry these days! In a modern JavaScript application, many clicks that “go somewhere” also “do” a lot of things.
Here’s the mental model I use: what would the customer think is happening? When they click “log out”, what would be their mental model? “Go somewhere”, or “do something”?
A programmer knows that logging out is doing something: changing the state of authentication. A customer might think something similar– the application is doing something called logging me out. The fact that it “goes” to the login page afterward is maybe just a detail. I’d implement it as a button.1
A few more examples:
- Updating the user’s profile? Button
- Visiting the dashboard? Link
- Skipping a step in a wizard? Link
- Closing a modal form? Button
- Sending a chat message? Button
You aren’t going to always get it right, and sometimes, you can bend the rules. When it doubt, be consistent.
Clickable Elements Need Signifiers
Clickable elements need signifiers.
In The Design of Everyday Things, Don Norman discusses affordances and signifiers. Affordances are what actions are possible; signifiers are perceptible signals about those actions. Links and buttons have clear signifiers. When you’re using something else, you need to add signifiers.
Link signifiers are universal. They are a different color, are often underlined, and have a pointer cursor that makes that little hand show up when you hover over them. Many have a hover state and most have a visited state.
Button tend to benefit from skeuomorphism– they look buttons in the real world. Many have hover states, some have pointer cursors, and some have processing states like spinners, changing text, or temporary disability when processing.
Clickable things that are not links or buttons need signifiers, too! Sometimes they are in a context like a menu where almost everything is clickable, and that’s enough. Other times, you might need to add a drop shadow on hover, pointer cursor, call-to-action, or hover state. Pick one or multiple.
A clickable div
without any signifiers is rarely going to be clicked on. Add
signifiers.
Examples
Here are a few examples:
- A “log out” button with a hover state and a pointer cursor. When you click it, it’s disabled with a spinner, and when complete, the customer is logged out.
- An “about us” link in the footer of a webpage. It’s rich with signifiers like an underline, hover and visited colors, and a pointer cursor. When a customer clicks it, they see the “About Us” page.
- A “subscribe” button next to an email input for a newsletter subscription. Clicking it submits an email.
Here’s one non-link/button example:
- A clickable row in a table. It has to be a
tr
because of table nesting rules, but we want it to be clickable, so this is a rare exception to our first argument. To compensate for not using a button or link, we’ve added signifiers of a border, a hover state, and a pointer cursor. And we aren’t confusing the UX with links or buttons inside the row that draw attention away from it and fight for click captures.
Wrapping Up
To summarize:
- Most clickable elements should be links or buttons.
- Use buttons and links for their respective jobs.
- Clickable elements need signifiers.
There’s a lot more to this, and best practices continue to evolve. That’s a good thing! But these principles have lasted a while and following them works.
-
This example UX problem is often implemented as something that looks like a link. Stay safe out there. ↩︎