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