Great question! The value of `role` tells the screen reader the element is a button, that's all. To be focusable, handle touch, mouse and keyboard (space and enter ofc) inputs you could write bespoke JS and CSS, or change `div` to `button`
This is all true and correct advice. I’m reticent to add this because, but for those curious about how close you can get to native <button>/<input type="button"> without the native form control, tabindex=0 gets you pretty much there. They’re all effectively useless without JS and all have the same styling capabilities these days, however, so better to just use the thing that’s designed to be a button unless you have a really special use case that you really understand (you don’t).
That doesn't quite get you there, though. For example, it doesn't submit a form it is contained in when clicked.
There are some use cases where a <button> won't work (eg if you want to use flexbox), but even then I'd first re-evaluate how important that use case is, then reach for a properly tested library to turn another element effectively into a button [1], and only then try to implement it myself and probably forget some built-im functionality, breaking things for users and costing me lots of time.
Flexbox not working in buttons is news to me (and I use display: flex and display: grid all the time). I just tested in both Chrome and Firefox and display: flex works just fine inside a button.
I think there was a bug in Chrome a couple of years ago where they incorrectly denied some element the ability to be flex containers (<fieldset> was a really annoying case of this) but I think that is fixed now.
The only case that I can think of where you can’t use a <button> is if you have nested interactive elements (a button within a link/button). There are sometimes ways around that (absolute positioning of the outer link/button) but sometimes there aren’t and then you need to re-implement a fake button from a <div>.
Oh hmm yeah, you're right, I must've mixed it up with another example in my mind. Ah well, replace that with your example in my comment, and the point stands :)
Indeed, I just remembered I actually have a SO answer where a “fake” button is one of the solutions ( https://stackoverflow.com/a/55155649/2444959 ). This question was about having an enabled button inside a disabled fieldset.
I actually do think that use cases are rare, and when you need a fake button, there are probably better solutions (in the SO question, the question author probably just wanted <details> and <summary>) but—though rare—these cases do exist.