Weird, I always use buttons when I can, unless what I need is not actually a button, but something that performs and on-click sort of like a button, like a hyperlink that navigates you through the web app.
> This element does not announce itself as an interactive element to screen reader users.
Is this actually true nowadays? Given that advice like this is often parrotted by people who don't actually use screen-reading software, I sometimes wonder if this is a situation where we've just been saying this and repeating this advice; meanwhile, screen readers have obviously become sophisticated enough to recognize that a div with an onclick handler on it is probably, you know, clickable and interactive.
> 1. This element does not announce itself as an interactive element to screen reader users.
It has the "onclick" property set though. The other two points are pretty valid, however. It's a shame we don't have a proper "onsubmit" property or something like that. "Oninteract"?
A good addition to this article is that most buttons should have type="button" on them. By default, buttons are type="submit", which if contained inside a form will submit that form.
I'm sure there are some devs who reach for a div because they're unaware of the proper way to disable submit behavior.
My very similar pet peeve is about websites that use `onclick` handlers and similar to implement navigation. Just use a damn anchor tag, which gets you correct link behavior for free:
* works with middle click for new tab
* integrates with accessibility devices
* works with right click + open in new window or similar options
* etc. etc. etc.
If it's notionally navigation, don't use javascript soup: use a link.
> This element does not announce itself as an interactive element to screen reader users
Are you sure? Screen readers should be able to detect a div with a onclick as interactable, no? And if they can’t, that seems like an exceedingly simple fix. I’d be shocked if they can’t already detect onclick.
I wonder if the "React Ry–thought-leader-guy" crowd (I love this not-so-subtle reference to Ryan Florence) preferred div over button because of the built-in styles that browsers used to apply to button elements.
I would love to see this expanded into "Just use the HTML element that was built for that explicit purpose". I feel like your average SPA developer doesn't understand what even a quarter of the HTML elements are meant for and just reinvent the wheel every time.
I got bitten by this: user agent stylesheet contains "button {align-items: flex-start}" (at least in Chrome). The default behavior is "stretch". Spent an hour debugging why my flexboxs' sizes are wrong. I still want to use correct HTML elements as much as possible, but I do think using <div>s everywhere makes my small side projects so much easier, since I don't have to remember all the non-default behaviors.
Related, because I don't always get to talk about buttons:
In my day job's shared library, we made a Clickable component that basically exists to abstract away the decision to use a button or an anchor tag, and resets the styles so both elements act the same way (both by default and when we apply styles to each).
We'd have a lot of confusion on the design side about button-as-design vs button-as-function and now we don't have to deal with that at all anymore.
And since the styling's been reset in a predictable way, it takes away one of the bigger reasons why people go to divs in the first place.
The type of developers that would go with <div> in such cases are also those that know very, extremely little about semantic HTML and its purpose.
Then if one is challenged about using React or other heavy-JS framework when you don't really have to, the discussion will be met with utter even surprise that someone out there is actually not using React.
The web is darn simple, but we are the place where it is made extremely over engineered and expensive for both companies (salaries and 2-3x more staff needed than necessary because of the bloat) and users of their products (in terms of payloads).
And yet JS-heavy frameworks seems to have the best job market.
This is a good example of cases where LLMs can tend to write 'bad' code, because these patterns (i.e. reinventing wheels in the browser) are quite common in the wild, and LLMs tend to choose them over just using native features (such as buttons). I find myself telling Claude to revisit implementations and simplify them in these kinds of ways.
Another good example is bizarre error handling conventions when working in TypeScript. Claude will come up with tons of weird ways of doing this, using different approaches all over the place, but rarely consider simple patterns like 'return an expected value or an error'.
tbh, I've started to grow a disdain for front-end developers. It seems their favorite pastime is re-inventing the wheel, and every single time, they destroy something while gaining absolutely nothing.
Stop implementing date pickers when <input type="date"> exists.
Stop implementing smooth scrolling. Browsers already do it on their own, and your implementation will not work. Really, just don't mess with scrolling in general. Don't make scrolling have "momentum". Don't change scroll speed. One site I've been to goes out of its way to change how much a scroll wheel click scrolls the page. For fuck's sake, can someone explain to me why that would be a feature!? Why go out of your way to override a specific user preference!?
All this bullshit changes expected behaviors, reduces accessibility, reduces the performance of your web page (and therefore increases CPU and battery usage)...for no reason whatsoever.
A whole generation of people who click all over to find places that do something. People have this problem where they feel 'proudly vested' in learning things that just weren't designed well.
10 years ago someone decided that dragging links is so much more important than selecting text, selecting text is scarcely possible. I'm going to have to fork a browser to give link-dragging the demotion it deserves. It was probably those DIV guys.
> You shouldn’t, though! Seriously, just don’t fuck with focus order.
And here i am, wishing some would do just this. Especially creators of log in forms which make the “reveal password” button the next focus point instead of the “submit” button
35 comments
[ 2.6 ms ] story [ 56.0 ms ] thread- why do you need to listen for events at the document level?
not that i disagree with the article, but some arguments didn’t seem right.
Use elements as close to their original intention as possible
Is this actually true nowadays? Given that advice like this is often parrotted by people who don't actually use screen-reading software, I sometimes wonder if this is a situation where we've just been saying this and repeating this advice; meanwhile, screen readers have obviously become sophisticated enough to recognize that a div with an onclick handler on it is probably, you know, clickable and interactive.
It has the "onclick" property set though. The other two points are pretty valid, however. It's a shame we don't have a proper "onsubmit" property or something like that. "Oninteract"?
I'm sure there are some devs who reach for a div because they're unaware of the proper way to disable submit behavior.
* works with middle click for new tab
* integrates with accessibility devices
* works with right click + open in new window or similar options
* etc. etc. etc.
If it's notionally navigation, don't use javascript soup: use a link.
Are you sure? Screen readers should be able to detect a div with a onclick as interactable, no? And if they can’t, that seems like an exceedingly simple fix. I’d be shocked if they can’t already detect onclick.
In my day job's shared library, we made a Clickable component that basically exists to abstract away the decision to use a button or an anchor tag, and resets the styles so both elements act the same way (both by default and when we apply styles to each).
We'd have a lot of confusion on the design side about button-as-design vs button-as-function and now we don't have to deal with that at all anymore.
And since the styling's been reset in a predictable way, it takes away one of the bigger reasons why people go to divs in the first place.
The web is darn simple, but we are the place where it is made extremely over engineered and expensive for both companies (salaries and 2-3x more staff needed than necessary because of the bloat) and users of their products (in terms of payloads).
And yet JS-heavy frameworks seems to have the best job market.
Everything seems to be upside down.
Another good example is bizarre error handling conventions when working in TypeScript. Claude will come up with tons of weird ways of doing this, using different approaches all over the place, but rarely consider simple patterns like 'return an expected value or an error'.
Stop implementing date pickers when <input type="date"> exists.
Stop implementing smooth scrolling. Browsers already do it on their own, and your implementation will not work. Really, just don't mess with scrolling in general. Don't make scrolling have "momentum". Don't change scroll speed. One site I've been to goes out of its way to change how much a scroll wheel click scrolls the page. For fuck's sake, can someone explain to me why that would be a feature!? Why go out of your way to override a specific user preference!?
All this bullshit changes expected behaviors, reduces accessibility, reduces the performance of your web page (and therefore increases CPU and battery usage)...for no reason whatsoever.
10 years ago someone decided that dragging links is so much more important than selecting text, selecting text is scarcely possible. I'm going to have to fork a browser to give link-dragging the demotion it deserves. It was probably those DIV guys.
And here i am, wishing some would do just this. Especially creators of log in forms which make the “reveal password” button the next focus point instead of the “submit” button
Here's a tip for weirdo front-end devs that do this: You are not smarter than the people that created the spec.