321

Is it possible to focus on a <div> using JavaScript focus() function?

I have a <div> tag

<div id="tries">You have 3 tries left</div>

I am trying to focus on the above <div> using :

document.getElementById('tries').focus();

But it doesn't work. Could someone suggest something....?

Brett DeWoody
  • 59,771
  • 29
  • 135
  • 184
OM The Eternity
  • 15,694
  • 44
  • 120
  • 182

8 Answers8

619

Yes - this is possible. In order to do it, you need to assign a tabindex...

<div tabindex="0">Hello World</div>

A tabindex of 0 will put the tag "in the natural tab order of the page". A higher number will give it a specific order of priority, where 1 will be the first, 2 second and so on.

You can also give a tabindex of -1, which will make the div only focus-able by script, not the user.

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>

Obviously, it is a shame to have an element you can focus by script that you can't focus by other input method (especially if a user is keyboard only or similarly constrained). There are also a whole bunch of standard elements that are focusable by default and have semantic information baked in to assist users. Use this knowledge wisely.

Fenton
  • 241,084
  • 71
  • 387
  • 401
  • And what if in place of
    tag I am using ?
    – OM The Eternity Sep 07 '10 at 07:27
  • But this doesn't bring it to the user's attention, it simply makes it tabable. – Michael Shimmins Sep 07 '10 at 07:28
  • 7
    @Michael Shimmins, This allows the element to be focusable (in a non-standard way!) with `focus()`. – strager Sep 07 '10 at 07:34
  • IE does not support this :( – Babu James Feb 28 '13 at 06:26
  • 1
    @Babu James - IE definitely does support this. I just tested it in IE8 and it worked fine... – Ben Saufley Aug 06 '13 at 17:50
  • 1
    If you use a negative index (`tabindex="-1"`) then it will not be selectable via the tab key, but you can assign focus to it: http://snook.ca/archives/accessibility_and_usability/elements_focusable_with_tabindex – Olical Nov 25 '13 at 17:06
  • 2
    @Olical - I'm pretty sure that's exactly what it says in the last line of may answer. Let me know if you think there is a problem that needs an edit. – Fenton Nov 25 '13 at 21:05
  • @SteveFenton Oh, so sorry, and that's why you don't skim answers. At least I've added a link to an interesting article on the subject. Sorry about that! – Olical Nov 26 '13 at 10:21
  • 3
    If it wasn't clear, adding `tabindex` to an element will make it focusable, which enables the `focus()` and `blur()` methods, and then you can trigger a focus like this: `document.getElementById('tries').focus();` – pilau Dec 25 '14 at 09:20
  • "But this doesn't bring it to the user's attention" You can style it with CSS using `:focus`. Works on the major browsers, even on MSIE starting with 9. – bart Mar 24 '15 at 08:39
  • and also you can make the outline:0; using css so there will be no difference between simple and tab indexed div – Waqas Tahir Jul 15 '15 at 15:57
  • Thx, now I can focus an element for keyboard-scroll-control: `$('#scrollbykeyboard').attr('tabindex', 0).focus();` – Sebastian G. Marinescu Aug 15 '15 at 23:44
  • I appreciate this is an old answer, but giving a div a tabindex of -1 doesn't work in Firefox 42. I had to give it a positive tabindex. – Steve Owen Nov 13 '15 at 14:29
  • 4
    Hi @SteveOwen - it seems to still work in Firefox v42. I have added a snippet to this answer so you can run it and test. – Fenton Nov 13 '15 at 14:41
  • Hi @SteveFenton. You're right. I'm sorry. I should have been more specific. I wanted the browser to scroll to the element when it focused on it, and I couldn't get that to work with a tabindex of -1, only when I gave it a positive index. – Steve Owen Nov 16 '15 at 10:39
  • 12
    @SteveOwen using `window.location.hash = ...` is the way to do that. focus doens't mean "bring into view", it just means literally place the focus on that element. – Fenton Nov 16 '15 at 11:23
  • 2
    But when focused with javascript, the element doesn't seem to get the `:focus` css rules - https://developer.mozilla.org/en-US/docs/Web/CSS/:focus – commonpike Mar 07 '17 at 10:59
  • 2
    this is such a better answer. @community should mark it instead. – tatsu Sep 10 '18 at 15:33
  • 1
    Firefox 78 seems to allow user focus on elements with a negative tabindex. (Click on Element Z in the example, and you'll see what I mean.) – RobH Jun 24 '20 at 00:52
116
window.location.hash = '#tries';

This will scroll to the element in question, essentially "focus"ing it.

Casey Chu
  • 25,069
  • 10
  • 40
  • 59
94

document.getElementById('tries').scrollIntoView() works. This works better than window.location.hash when you have fixed positioning.

Thiem Nguyen
  • 6,345
  • 7
  • 30
  • 50
vinoths
  • 1,071
  • 2
  • 10
  • 13
  • 2
    Note that this solution will not work in IE, Opera or Safari. – Alec Rust Sep 25 '17 at 15:54
  • 2
    I just tried this in Chrome 65 and it does not work. The overlay div scrolls into view, but the focus is still in the background div. The only sure-fire way I know of is to have a tabbable element (using `tabindex` attribute) in the overlay div and use `focus()` on that element instead. – thdoan Apr 21 '18 at 20:53
  • @om-the-eternity already stated that he wants the div to call the attention of the user, so what he needs is not to actually focus (even when working it's not correct to do it) the div, but bringing it to the screen, this solves that – Omar Vazquez Jul 26 '18 at 04:21
  • If I do this in Chrome it keeps scrolling back to the still-focused input field. Especially if the page isn't done loading yet. – Roger Krueger Oct 31 '18 at 06:26
81

You can use tabindex

<div tabindex="-1"  id="tries"></div>

The tabindex value can allow for some interesting behaviour.

  • If given a value of "-1", the element can't be tabbed to but focus can be given to the element programmatically (using element.focus()).
  • If given a value of 0, the element can be focused via the keyboard and falls into the tabbing flow of the document. Values greater than 0 create a priority level with 1 being the most important.
Sarath Ak
  • 7,903
  • 2
  • 47
  • 48
  • Life saver, thanks. In Edge a div can be focused but not in Chrome without this trick. Accepted answer is great but I don't want additional part in the url. – Cal Feb 02 '19 at 15:43
  • This is def the best answer if you need to do some kinda JS Dom Manipulation for UI. Its really handy for allowing onblur to be used to dismiss elements such as menus or pop up – d0rf47 Jul 15 '22 at 19:23
21
<div id="inner" tabindex="0">
    this div can now have focus and receive keyboard events
</div>
ale
  • 6,369
  • 7
  • 55
  • 65
Azad
  • 5,144
  • 4
  • 28
  • 56
  • This works for me in Chromium/Chrome 46 only combined with `$('#inner').focus();` – TNT Nov 24 '15 at 08:07
13

document.getElementById('test').onclick = function () {
    document.getElementById('scripted').focus();
};
div:focus {
    background-color: Aqua;
}
<div>Element X (not focusable)</div>
<div tabindex="0">Element Y (user or script focusable)</div>
<div tabindex="-1" id="scripted">Element Z (script-only focusable)</div>
<div id="test">Set Focus To Element Z</div>
san jing
  • 143
  • 1
  • 5
  • 3
    Nice answer, but would be good to also add some explanation to your code example. – Wilt Oct 08 '21 at 13:43
3

I wanted to suggest something like Michael Shimmin's but without hardcoding things like the element, or the CSS that is applied to it.

I'm only using jQuery for add/remove class, if you don't want to use jquery, you just need a replacement for add/removeClass

--Javascript

function highlight(el, durationMs) { 
  el = $(el);
  el.addClass('highlighted');
  setTimeout(function() {
    el.removeClass('highlighted')
  }, durationMs || 1000);
}

highlight(document.getElementById('tries'));

--CSS

#tries {
    border: 1px solid gray;
}

#tries.highlighted {
    border: 3px solid red;
}
Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
1

To make the border flash you can do this:

function focusTries() {
    document.getElementById('tries').style.border = 'solid 1px #ff0000;'
    setTimeout ( clearBorder(), 1000 );
}

function clearBorder() {
    document.getElementById('tries').style.border = '';
}

This will make the border solid red for 1 second then remove it again.

Michael Shimmins
  • 19,961
  • 7
  • 57
  • 90