0

So basically i have a React's div wrapper that i built to act as a button for clickable block with complex content that no button or link can cater.

<div
      ref={ref}
      role="button"
      tabIndex={0}
      aria-label={ariaLabel}
      {...otherProps}
    >
      {children}
    </div>

Where the children content is basically any large content that usually cannot be put inside a button or link such as multi layer of divs or images. This wrapper is intended for any clickable block that needs to display rich display content like card.

The only problem is that, when going through sonarcloud scan, it threw me this error

Use <input type="button">, <input type="image">, <input type="reset">, <input type="submit">, or <button> instead of the "button" role to ensure accessibility across all devices.

which obviously cannot be done here because button does not support such contents. I dont want to ignore this error if possible by skipping it using suppression annotation or disabling comment, but even if i set the role properly along with its tab index to comply with its ARIA rule, i just couldn't get over the error. The component that uses this wrapper is set to be clickable as a whole, not just certain part of its content.

So what is the proper way of doing this wrapper or div as a clickable instead of just use button and link to comply with sonarcloud's rules? If it can be done with button, i would do it, but im sure there are contents within the web page where you want to have a clickable component that has complex contents on it, which no button and link can work.

5
  • Relevant ~ github.com/whatwg/html/issues/9705. Sure would be nice if the <button> children rules were relaxed Commented Jan 16 at 0:52
  • <a> tags on the other hand permit just about anything. What is the reason behind not considering an anchor? Commented Jan 16 at 0:56
  • @Phil while anchor seems better than button, but the one i attempt to do is a universal one that allows whatever kind of children content to be displayed in it. Anchor is restricted in that sense since it doesn't allow any other interactive elements to be its children / content. But i havent really try using anchor as a clickable block so far, maybe i can give it a try first. Commented Jan 16 at 1:54
  • Yeah, having interactive child elements would lead to undefined behaviour Commented Jan 16 at 3:27
  • Clickable cards should probably not be wrapped in a button or link. adrianroselli.com/2020/02/… Commented Jan 16 at 6:44

1 Answer 1

1

Basically you have two problems.

The content of a button must be short

A button isn't made to have large contents inside it, and the fact that the button is standard <button> or faked with ARIA role=button doesn't change anything (for screen readers and other assistive tools, both appear the same for the user at the end, that's precisely the purpose of ARIA).

Remember that the whole content of the button is read in one go by the screen reader when it is focused, makes a giant label in a list of buttons to click on, and also that you might need to speak aloud the whole content to activate it with voice control.

It's unclear which action a click performs when a lengthy content is read with a lot of information. Does it open a page with more details ? Is the product directly added to cart ? Does it immediately launch a rocket missile without any other confirmation ? Even if the actual action performed is written in clear somewhere in the middle, it is flooded by all the rest and so unoticible.

Therefore, the content of a button has to be short, directly telling what's going to happen if you click, otherwise it is, practically speaking, not accessible, or excessively painful to use.

Nested interactive elements

You can't simply say that a button can have arbitrary content. You should prevent that, or change completely your design. In fact, as soon as you have another interactive element inside your button, you are running into issues. This is well known as the nested interactive zone problem, which must be avoided at all cost.

  • When pressing enter or clicking on the inner element, should the outer element also be triggered ?
  • When focusing the outer element, should the content of the inner element also be read by screen readers ? usually it is and it creates a lot of confusion because some content is read twice, or what is read doesn't correspond to the performed action
  • Visual focus indications might be unclear as well
  • You can easily click by misstake slightly outside the inner element, and trigger the outer element instead while it wasn't intended
  • When the mouse is inside the inner element, do you consider it to be inside or outside the outer element ?
  • etc.

All these questions haven't a definitive clear answer. Sometimes you would prefer an answer to be yes, and sometimes no. It's difficult and not recommended to go against default behavior. It could be different with different browsers/OS/etc.

A fully clickable card isn't a button

As you should have now understood, your fully clickable card shouldn't be considered as a button. You should neither use <button>, <input type="button"/>, nor role=button tabindex=0. All are WRONG!!!

Even if you prevent nested interactive elements by any mean, the length and flood of information given by a single card read as a whole is still a problem

A possible solution could be to keep the entire card clickable as it is now, but don't make it focusable. However, be very cautious, because by doing so, it's no longer accessible to screen reader and keyboard only users, among others. You have to provide an alternative mean to open the card. You can, very simply, add an explicit "More details" link or button somewhere, or use the title of the article as a link, etc.

See for example this question and the linked article. The card in the example stays fully clickable, but screen reader and keyboard only users interact with an heading link, which is the title of the article. This could be a solution for your case, too.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.