117

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.

Community
  • 1
  • 1
Alvis
  • 3,543
  • 5
  • 36
  • 41
  • possible duplicate of [how to make a DIV unfocusable?](http://stackoverflow.com/questions/716235/how-to-make-a-div-unfocusable) – thSoft Jan 21 '14 at 10:09
  • 6
    The question is phrased wrong. It should read: "How to make an HTML element non-tabbable?" which is what the original poster wants. – ShortFuse Oct 29 '18 at 18:35

10 Answers10

147
<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

Martin Thoma
  • 124,992
  • 159
  • 614
  • 958
Fedor Skrynnikov
  • 5,521
  • 4
  • 28
  • 32
  • 1
    Bear in mind that it's invalid HTML to have a number below 0 as the value of `tabindex` (although I *think* it's valid in HTML5). – James Allardice Feb 05 '12 at 19:24
  • 82
    Note that an element with a negative tabindex is still *focusable*, it just cannot be reached using sequential focus navigation (i.e. tabbing). – Alohci Feb 05 '12 at 19:43
  • This does not work in IE for certain elements (eg. SVG nodes). See Zohid's answer below, for a solution. – Krisztián Balla Nov 06 '19 at 12:49
  • 3
    just a side note for React devs: don't forget the camelCase and the brackets: tabIndex={-1} – e18r Apr 28 '20 at 13:23
  • I downvoted this answer, since it is not what the question is exactly about. In my case it didn't help me. The element is being omitted while you using Tab, but still can be auto-focused. So to make it unfocusable anyway, we need to add `disabled` attribute, as it is mentioned in @Randy's answer. – Dzmitry Alifer Dec 29 '20 at 13:10
40

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.
Randy
  • 9,419
  • 5
  • 39
  • 56
  • 10
    This is not what the OP is looking to achieve. Your example would make that textbox disabled. A disabled textfield is not the same as an unfocusable one. He still wants to make his button clickable but wants his textfield to still have the focus while he's clicking his button. If an item is unfocusable then interacting with it by clicking, etc, will mean that the current focused item stays focused. That's that the OP wants to achieve. – Richard Aug 12 '18 at 07:45
  • 5
    This doesn't work for non-`input` elements -- if I don't want a `
    ` to be able to receive focus, `disabled` does not help.
    – Coderer Mar 04 '20 at 10:00
19

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:

/**
 * @this {HTMLElement}
 * @param {FocusEvent} event
 * @return {void}
 */
function preventFocus(event) {
  if (event.relatedTarget) {
    // Revert focus back to previous blurring element
    event.relatedTarget.focus();
  } else {
    // No previous focus target, blur instead
    this.blur();
    // Alternatively: event.currentTarget.blur();
  }
}

/* ... */

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

For safe typechecking, you can perform if (event.relatedTarget instanceof HTMLElement) instead if (event.relatedTarget).

ShortFuse
  • 5,970
  • 3
  • 36
  • 36
5

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.

rie819
  • 1,249
  • 12
  • 19
4

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.

Maciej Krawczyk
  • 14,825
  • 5
  • 55
  • 67
3

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

Chinmoy
  • 1,750
  • 2
  • 21
  • 45
2

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

Krisztián Balla
  • 19,223
  • 13
  • 68
  • 84
Zohid
  • 438
  • 1
  • 3
  • 14
1

If its an individual element like a button or an input field, you can use the disabled attribute.

Example:

<button disabled>Try to Click Me!</button>

But if its a container-like element, like a form, setting the disabled attribute to that form doesn't work, and its children will NOT be disabled/non-focusable.

In that case, use the inert attribute.

<form inert>
  <button>Try to click Me!</button>
</form>

All of its children, i.e., the entire form will become unfocusable.

0

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.

Alexander Abakumov
  • 13,617
  • 16
  • 88
  • 129
0

$("#element").prop({"readonly":true,"tabindex":-1}).css('pointer-events','none');

Shubham Malik
  • 105
  • 1
  • 2
  • 9