- Daily Tips
 - October 31, 2025
 
One of the weirdest “debates” I seem to perpetually have with framework-enthusiastic developers is whether or not a <div> is “just as good” as a <button>.
Spoiler: it’s not. Let’s dig in.
The problem
Among the React crowd, and also among people who seem to enjoy HTMX, I see a lot this…
What’s wrong with this?
- This element does not announce itself as an interactive element to screen reader users.
 - You can’t focus on a <div> with a keyboard.
 - The event only fires on click, not when the Enter or Space Bar keys are pressed (again, keyboard users).
 
I’ve seen this in a lot of code bases. I’ve seen it in a lot of demos.
I’ve had arguments with a very prominent React thought leader whose name starts with R who insisted that using a <div> was “more accessible” than using a <button>, and that Twitter made the right decision in using this pattern in their app.

It’s wrong. It’s all wrong.
The “fixes” aren’t
Many HTML elements have implicit roles that tell assistive tech like screen readers what they do.
The <button> element is one of them. It has an implicit [role] of button, which tells screen reader users it can be interacted with and will trigger some type of behavior in the app.
The HTML [role] attribute can be used to add or modify the role of an element. And so, folks like React Ry–thought-leader-guy will say stuff like (I’m paraphrasing)…
That attribute exists for a reason. You can add [role="button"] to a div to give it the correct semantics.
OK, that addresses one issue.
That role doesn’t affect focusability (or lack thereof) or keyboard behavior. Visually impaired users and people who navigate with a keyboard still can’t use it.
“No worries!” they say. “We can fix that, too!”
You can make the element focusable with the [tabindex] attribute.
You shouldn’t, though! Seriously, just don’t fuck with focus order.
It’s way too easy to go down this path and then fuck it up and have folks jumping all over the page instead of navigating through in the normal and expected order.

And again, still no keyboard interactivity.
But don’t fear! You can add that, too. You just need to listen for all keydown events, and then filter them out by event.key so that you only run your code if the Enter or Spacebar keys were pressed (the latter means checking for a literal space: ' ').
That can’t run on the element, either. You’ve got to attach that even to the document and figure out which element has focus.
So um… ok, I guess it is technically a fix, but…
You’ve just recreated all of the functionality a <button> gives you for free
Seriously, WTF would you do that?!?
All of these hoops to write this HTML…
When you could write this HTML instead…
A <button>…
- Has the correct [role] implicitly.
 - Is automatically focusable.
 - Fires a click event in response to Enter and Spacebar presses when it has focus.
 
Look, I’m a lazy developer.
And I suspect, if you’re someone who loves tools like React, you probably are, too. It’s cool, I get it! The best code is the code you didn’t write and all that.
So, be even lazier.
Use the correct element for the job, and avoid writing a bunch of extra code!
.png)
  

