'difference between having a click handler on a button or on its parent?

Between

<button onClick={...}>Click me</button>

and

<span onClick={...}>
  <button>Click me</button>
</span>

are there any differences for the user? I know that the click event will always bubble up to the span element, but are there any accessibility issues or unintended consequences that could arise from this?



Solution 1:[1]

There is a massive difference!

If you tab to a <button> so it is focused you can activate it using Enter and it will activate the click handler. It will not do this with a <span> (even if you add tabindex="0" to the <span> so it is focusable).

Also having a click handler on a <span> around a <button> will cause issues as you then have nested active elements. This means that when you click on the <button> that is within a <span> there is no way of knowing which element is supposed to fire an event (is it the <span> click handler or the <button> click handler?)

The question is, why do you want to attach the handler to the <span> as it may be that there is a better way to do what you are attempting. Let me know and I will see if I can help you structure things better / work around the problem!

Solution 2:[2]

since your question is about accessibility, you sure shouldn't do this because you have a native element for "clicking things" in HTML, but if you insist you can make a span work as a button by:

  • adding the role='button' attribute
  • handle the aria-pressed attribute value
  • define a value for tabindex attribute.

if you didn't do this the screen readers users will have a difficult time in your website

this link contains an example how button can be considered a div with extra attributes: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/button_role

Solution 3:[3]

In that setup, you should be fine. If however you had a <span> inside of the <button>, then that's when you'll run into issues because a button should not contain children elements, only the value.

<button type="button" onclick="alert("Yo");"></button> = works

<button type="button"><span onclick="alert("Yo");"></button> = fails

And then I believe Firefox handles these events differently to Chrome, but the latest builds should be ok.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Graham Ritchie
Solution 2 Muhammed Yasser
Solution 3 Andrew West