Make an HTML element non-focusable

HtmlDom

Html Problem Overview


Is it possible to make an HTML element non-focusable?

I understand that a list of elements that can receive focus can be defined and that a user can navigate through these elements by pressing a Tab key. I also see that it is up to the browser to control this.

But maybe there is a way to make certain elements non-focusable, say I want a user to skip a certain <a> tag when pressing a Tab.

Html Solutions


Solution 1 - Html

<a href="http://foo.bar" tabindex="-1">unfocusable</a>

A negative value means that the element should be focusable, but should not be reachable via sequential keyboard navigation.

See also: developer.mozilla.org

Solution 2 - Html

To completely prevent focus, not just when using the tab button, set disabled as an attribute in your HTML element.

<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>

<input class="form-control" type="text"> Click this, you can see it's focusable.

<input class="form-control" type="text" readonly>  Click this, you can see it's focusable.

<input class="form-control" type="text" readonly tabindex="-1">  Click this, you can see it's focusable. Not tab'able.

<input class="form-control" type="text" disabled>  Click this, you can see it's <strong>not</strong> focusable.

Solution 3 - Html

In order to make an prevent an element from taking focus ("non-focusable"), you need to use Javascript to watch for the focus and prevent the default interaction.

In order to prevent an element from being tabbed to, use tabindex=-1 attribute.

Adding tabindex=-1 will make any element focusable, even div elements. This means when a user clicks on it, it would likely get a focus outline, depending on the browser..

You would ideally, want this:

function preventFocus(event) {
  event.preventDefault();
  if (event.relatedTarget) {
    // Revert focus back to previous blurring element
    event.relatedTarget.focus();
  } else {
    // No previous focus target, blur instead
    event.currentTarget.blur();
  }
}

/* ... */

element.setAttribute('tabindex', '-1');
element.addEventListener('focus', preventFocus);

Solution 4 - Html

TabIndex is what your looking for: http://www.w3schools.com/jsref/prop_html_tabindex.asp.

When you set a tabIndex value to -1 you will skip it when tabbing through your form.

Solution 5 - Html

For the element you do not want to be focused on tab, you have to put the tabindex as a negative value.

Solution 6 - Html

I used focusable="false", because tabindex="-1" was not working in IE.

http://www.w3.org/2000/svg" focusable="false">

Solution 7 - Html

In case you are looking for a global solution:

<a href="#" class="__nofocus" tabindex="-1">Link</a>

document.body.addEventListener('focusin', (e) => {
  if (e.target.classList.contains('__nofocus')) {
    e.relatedTarget ? e.relatedTarget.focus() : e.target.blur();
  }
});

It should work for anchors, buttons and anything else that can receive focus by default. Don't forget to set tabindex="-1" as well as the element would be unpassable by Tab-key navigation.

Solution 8 - Html

Making a focusable-by-default HTML element a non-focusable one isn't possible without JavaScript.

After diving into focus-related DOM events, I've came up with the following implementation (based on the @ShortFuse's answer, but fixed some issues and edge cases):

// A focus event handler to prevent focusing an element it attached to
onFocus(event: FocusEvent): void {
    event.preventDefault();

    // Try to remove the focus from this element.
    // This is important to always perform, since just focusing the previously focused element won't work in Edge/FF, if that element is unable to actually get the focus back (became invisible, etc.): the focus would stay on the current element in such a case
    const currentTarget: any | null = event.currentTarget;
    if (currentTarget !== null && isFunction(currentTarget.blur))
        currentTarget.blur();

    // Try to set focus back to the previous element
    const relatedTarget: any | null = event.relatedTarget;
    if (relatedTarget !== null && isFunction(relatedTarget.focus))
        relatedTarget.focus();
}

// Not the best implementation, but works for the majority of the real-world cases
export function isFunction(value: any): value is Function {
    return value instanceof Function;
}

This is implemented in TypeScript, but could be easily adjusted for plain JavaScript.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlvisView Question on Stackoverflow
Solution 1 - HtmlFedor SkrynnikovView Answer on Stackoverflow
Solution 2 - HtmlRandyView Answer on Stackoverflow
Solution 3 - HtmlShortFuseView Answer on Stackoverflow
Solution 4 - Htmlrie819View Answer on Stackoverflow
Solution 5 - HtmlChinmoyView Answer on Stackoverflow
Solution 6 - HtmlZohidView Answer on Stackoverflow
Solution 7 - HtmlMaciej KrawczykView Answer on Stackoverflow
Solution 8 - HtmlAlexander AbakumovView Answer on Stackoverflow