Home > Mobile >  How to make a div and all its descendants unfocusable
How to make a div and all its descendants unfocusable

Time:12-22

I was trying to make a div and all its descendants unfocusable. I used a tabIndex -1 on the root div. But that was making focus move to its first focusable child. (The default behavior) Is there a workaround for this issue?

Example code

const SomeFunctionComponent = () => {
  // ... some logic ...

  const someTrustedHtml = `<p>Hello <a href="stackoverflow.com">World!</a></p>`;
  const content = React.createElement("div", {
    className: "some class name",
    dangerouslySetInnerHTML: {
      __html: someTrustedHtml;
    },
    tabIndex: -1, /* "tabindex": -1 does not work */
    // None of these options helped either
    // "data-is-focusable": false,
    // "aria-hidden": true,
    // disabled: true,
    // role: "presentation"
  });

  // ... more logic ...
  
  return (
    <div>
      {content}
      <button onClick={() => console.log("hello world")}></button>
      {/* some tab focusable elements */}
    </div>
  );
}

expected behavior: When SomeFunctionComponent gets focus, focus would move to the button

actual behavior: focus goes to the link in the dangerouslySetInnerHtml

CodePudding user response:

tabindex is not inheritable. You have to set it on every element that is natively focusable.

Interestingly enough, the spec says that setting it to -1 does not cause an element to be non-focusable, but I use that all the time and it works on all browsers.

Note that the tabindex attribute cannot be used to make an element non-focusable. The only way a page author can do that is by disabling the element, or making it inert.

CodePudding user response:

There is no simple solution. As the other answer says, you have to iterate through all focusable inside the div.

In fact, rather than setting tabindex=-1 on all focusable elements inside the div, it would be better to hide the div altogether via display:none or hidden attribute, or using disabled attribute for form fields as a second choice. Hidden elements aren't focusable.

Having the disabled attribute set is important to let the user visually see that he/she can't currently use the field, as well as telling screen reader users of that fact. So, it's preferable. Setting the disabled attribute to true automatically implies that the field isn't focusable anymore.

As a reminder, setting tabindex=-1 doesn't make an element totally unfocusable. It doesn't allow the user to focus it anymore using tab or other normal ways, but it remains focusable programatically (using the focus() method). Note that it's perfectly possible to bypass direct unfocusability with user scripts.

  • Related