Pushing Buttons
Buttons vs. Links
Hopefully by now, most of us understand when we should be using button
and a
elements in our work. If not, the general consensus on what to use, and when, usually comes down to this conventional wisdom:
Buttons should be used for specific interface actions.
Typical use cases for implementing a button
include:
- Opening modal windows
- Disclosure widget (Accordions) interactions
- Closing interfaces, etc.
Links on the other hand, should be used for navigation.
Use cases for hyperlinks include:
- Navigating to other pages on your site or across the web
- Anchoring to content fragments on your site or across the web
Sometimes knowing which to use can be a little tricky. For example, buttons that move content within a carousel (Please don't use carousels if you don't need them.), could be considered in-page navigation, but also a form of disclosure. However, when in doubt, my best advice is to use button
. So far, this has worked out pretty well for me.
Understanding Roles
While it may not have great bearing on visual users, those who use assistive technology (AT) greatly benefit from the correct choices we make with our mark-up. All rendered HTML elements have an inherent role assigned to them.
You can access these roles with your favorite browser development tool.
These roles are often read back to AT users. For example, landing on a button labeled "Search Jobs" with the NVDA screen reader, will announce:
"Search Jobs, button..."
Understanding that this interaction point is a button, helps improve the perception of the element and the action to expect when an element is interacted with. Now seems as good a time to suggest getting better acquainted with a WCAG concept known as POUR (Perceivable, Operable, Understandable, and Robust), so read up!
Buttons do things; hyperlinks navigate.
When we use links where buttons should be used (and vice versa), we break this expectation.
Keyboard Benefits
Using the right element for the job has other benefits, too. For example, keyboard users will expect both the return and space keys to initiate an action. When you use the button
element, there will be no need to code a second event for keypress
, as the single click
event will work with both of these keys. Efficient!
Hyperlink Suppression
While we are on the subject of hyperlinks, let's jump back (pun intended) to anchors for a moment.
We know that anchors can be destinations to sections within our websites. However, in an effort to be slick, we often suppress the native behavior of these links, using JavaScript, to smoothly scroll users to the desired position within a page. There are some issues with this technique that we should be mindful of:
- Keyboard focus is lost. By not applying focus to the area you are targeting, keyboard users are left behind and will have to continue tabbing from the original, pressed position.
- Animating the scroll can be problematic for those with sensory disorders.
- The hash in the URL is often removed (via
return false
in JavaScript). This creates a lost opportunity to share specific content on social media or with friends, family and colleagues.
Solutions
The best solution, and the one you should probably push for amongst stakeholders, is to simply allow anchors to work as they inherently do. Leave the fancy scrolls and risks that come with suppression, behind. This solves all three issues previously mentioned. However, I do live in the real world and understand that you may be required to implement a smooth scrolling behavior, so let's take a look at an uncommon approach. Again, while JavaScript is usually the de facto method for controlling scroll behavior, I think CSS offers a far more elegant solution:
html {
scroll-behavior: smooth;
}
Using scroll-behavior: smooth
not only allows us to include the obvious behavior for all anchors across our site, but also allows us to retain our URL hashes without the nasty jump. The focus issue is also solved, since the native behavior for anchors is to apply focus to their target elements. But what about sensory concerns?
@media (prefers-reduced-motion: no-preference) {
html {
scroll-behavior: smooth;
}
}
For you Sass lovers in the audience:
html {
@media (prefers-reduced-motion: no-preference) {
scroll-behavior: smooth;
}
}
By using the prefers-reduced-motion
media query, we can honor a user's operating system settings to disallow animations. This may not be perfect for all use cases, like people with temporary disabilities (migraines, etc.), but it is a step in the right direction.
Example
You can check out an example of this behavior on this very page! As an added bonus and to keep it all in the CSS family, using scroll-behavior
and prefers-reduced-motion
with the :target
selector, helps us to create a very seamless and accessible user experience. Look ma, no JavaScript!
Support
Support for scroll-behavior
is very good across the board. I personally see no harm in using it and to allow the anchors to fall back to their default behavior if CSS support is not present in an older browser. Progressive enhancement at its best. However, if full support is what you require, then you'll have to find a polyfill or just roll the same behavior using JavaScript, but please do not forget to include support for all the issues mentioned here.
The prefers-reduced-motion
media query also enjoys wide support, so be sure to include it in any animation work you may produce.