Disclaimer: This write-up is the first part of a valuable two-part series. While it provides comprehensive resources and requirements to understand the impact of semantic HTML on accessibility, it does not include code solutions. Part 2, which is equally important, will delve into the coding aspect, offering detailed solutions. This version is tailored for workshop use, encouraging hands-on learning and problem-solving.
Here's the 🏃 TL:DR 🏃 version for the speed readers:
🚫🚫 div[role="button"]
🚫🚫
The div
element, as per its HTML Standard definition, is non-interactive and therefore inaccessible. This can have significant implications for the usability and inclusivity of your code. For interactive elements, it's crucial to opt for an interactive HTML element instead.
// 😱😱😱 - Avoid at all costs
<div
onClick={handleClick}
className="btn"
role="button"
tabIndex="0"
/>
💫💫 Let the <button />
fulfill its destiny 💫💫 or as MDN puts it,
The
<button>
HTML element is an interactive entity activated by various user inputs. Once activated, it performs actions like submitting forms or opening dialogs.
// 💅💅💅 - Fully accessible and semantic
<button onClick={handleClick}>Click me</button>
By all means, this is meant to serve as a guiding principle and thought exercise in hopes of preventing you from ending up like this engineer on Stack Overflow:
We all have been there; we just need to make that div.card
component clickable. This post is not intended to have you turn everything into buttons. By the end of this post, we hope you are better equipped to respond to and wrestle with all the accessibility challenges we face. More importantly, correct the habit that often places us in those challenging situations. Remember, you're not alone in this struggle.
Let's be honest—we've all been there. The div
is often our go-to when in doubt about which HTML element to use. It's versatile, easy to style with CSS, and seems to do it all. But have you ever stopped to consider the cost of semantics and accessibility?
Indeed, one could muscle through accessibility requirements using div
s. Many WAI-ARIA Roles examples on MDN apply to div
elements. Even MDN's button role description mentions div
s but cautions against their risks. For example:
<div id="saveChanges" tabindex="0" role="button" aria-pressed="false">Save</div>
Even the W3C outlines a non-semantic approach that's safer, yet engineers frequently opt for potentially risky practices, risking business-damaging accessibility consequences.
The <button>
vs <div>
debate is not just theoretical—it has real-world implications. 20% of internet users access it through assistive technology. 20% is a lot of people. If the TL;DR didn't convince you to use a button for button-like actions, perhaps you're here for the memes. Welcome!
Imagine a scenario where a Product Owner requests a list of clickable product cards, with about 20% of traffic coming from assistive device users. Each card should:
- Be linked and clickable
- Contain more than one link
- Be semantically structured for assistive tech
- Be selectable like regular links
- Support right-click and keyboard shortcuts
- Have focusable elements for tab navigation
Reflecting on this journey from divs to buttons, it's clear that semantic HTML isn't just about following standards—it's about embracing accessibility, maintainability, and inclusivity. As we refactor our way through the codebase, let's remember the power of a well-placed <button>
and the broader impact of our coding choices.
Sources:
- W3Docs, CSS Tricks, Scott O'Hara's Blog, Gale Blog, Medium articles, and the W3C and HTML5 specifications provide a wealth of information on the importance of semantic HTML and alternatives to using
div
elements for interactive purposes.
This was me the morning I started writing this up