It's remarkable how little I've seen this discussed, but there's something about <button>s that I came across recently that confused me for a while.

The following hastily-put-together pen illustrates the problem:

We have a button, all of whose children are absolutely positioned relative to some ancestor of the button. The button itself is hidden from view. In all major browsers except Firefox (I've tested in Chrome, Internet Explorer, Safari and Opera), clicking one of the children triggers the button's click event listener. In Firefox, however, nothing happens at all.

This seems inconsistent with how events are normally handled – event propagation dictates that if one of the coloured squares is clicked, the target's ancestors, including the button, should respond. Indeed, this is exactly how Firefox behaves in my example if I replace the button with an <a>.

The closest I've come to an explanation is in gfullam's comments to a Stack Overflow answer. He suggests that Mozilla are just following the W3C specification, which states that a button can take any phrasing content as long as it has no interactive descendants. But this seems to be a misreading of the spec, the idea of which is that you shouldn't nest interactive content such as <button>s (which makes perfect sense).

In the real-world scenario in which I encountered the problem, I had an image and some text and wanted clicking either to trigger my event handler. I thought that grouping the two in a <button> would be the most semantic approach – but I ended up using an <a>.

I invite comments from anyone with a better idea of why Firefox handles buttons in this unique way.

1,342 2 5