Make an HTML element non-focusable
Asked Answered
R

10

123

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.

Rusticate answered 5/2, 2012 at 19:6 Comment(2)
possible duplicate of how to make a DIV unfocusable?Muddleheaded
The question is phrased wrong. It should read: "How to make an HTML element non-tabbable?" which is what the original poster wants.Raneeraney
J
151
<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

Jorry answered 5/2, 2012 at 19:11 Comment(5)
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).Languedoc
Note that an element with a negative tabindex is still focusable, it just cannot be reached using sequential focus navigation (i.e. tabbing).Lying
This does not work in IE for certain elements (eg. SVG nodes). See Zohid's answer below, for a solution.Manipulate
just a side note for React devs: don't forget the camelCase and the brackets: tabIndex={-1}Prager
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 <kbd>Tab</kbd>, 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.Inhibitor
P
42

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.
Phylogeny answered 10/4, 2017 at 14:34 Comment(2)
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.Ectoparasite
This doesn't work for non-input elements -- if I don't want a <div> to be able to receive focus, disabled does not help.Selfregulated
R
21

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).

Raneeraney answered 6/5, 2018 at 21:2 Comment(2)
Unfortunately on a slider (<input type="range") this renders the slider's behaviour very unpleasant : click still works but not drag.Moltke
focus isn't a cancelable event so preventDefault shouldn't have any effect. Reference: w3c.github.io/uievents/#focusThermoelectricity
E
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.

Eviaevict answered 5/2, 2012 at 19:10 Comment(0)
E
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.

Eubanks answered 20/11, 2021 at 8:0 Comment(0)
C
3

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

Cyrillus answered 5/2, 2012 at 19:32 Comment(0)
T
3

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.

Tracy answered 26/6, 2023 at 9:9 Comment(0)
C
2

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

Cootie answered 29/3, 2018 at 7:22 Comment(1)
This seems to be a non-standard attribute used by IE for svg elements: msdn.microsoft.com/en-us/ie/ff971943(v=vs.94)Manipulate
A
1

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.

Aristate answered 30/1, 2019 at 22:59 Comment(0)
R
0
$("#element").prop({"readonly":true,"tabindex":-1}).css('pointer-events','none');
Ruvolo answered 26/5, 2023 at 11:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.