Directing focus
Hey ,
I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.
Please upgrade (use this link) access this content.
I'm super eager to help you learn more!
Hey ,
I'm thrilled to help you learn JavaScript. Unfortunately, you've landed on a page where you cannot access with your current purchase.
Please upgrade (use this link) access this content.
I'm super eager to help you learn more!
Let’s say a user clicks on a button. If the button directs the user’s attention to something, you want to direct keyboard focus to that thing as well.
For example, let’s say we have an off-canvas menu. When a user clicks on the button, a menu pops out. We direct attention to the menu with an animation.
You want to direct focus to the menu for keyboard users. If the user presses Tab, you want to focus on the first item in the menu.

You can direct focus with Element.focus
Element.focus()
Element.focus lets you direct focus to focusable elements. By default, this means:
In the example below, if you click on the second button, the focus gets directed to the first button.
<button>Button</button>
<button>Go to previous button</button>
const buttons = document.querySelectorAll('button')
const firstButton = buttons[0]
const secondButton = buttons[1]
secondButton.addEventListener('click', event => {
  firstButton.focus()
})

Note: Focus also gets directed if the user interacts with the button with Space or Enter. This is because Space and Enter keys trigger a click event when they’re used on buttons.

Element.focus can only direct focus to focusable elements. It cannot direct focus to non-focusable elements. The code below does nothing. Focus remains on <button>.
<p>The quick brown fox jumps over the lazy dog</p>
<button>Go to paragraph</button>
const button = document.querySelector('button')
const paragraph = document.querySelector('p')
button.addEventListener('click', event => {
  paragraph.focus()
})

If you want to direct focus to a non-focusable element, you need to add tabindex to the element. In the example below, the paragraph gets focus when users click on the button.
<p tabindex="-1">The quick brown fox jumps over the lazy dog</p>
<button>Go to paragraph</button>

Links let you direct focus when:
href begins with a #.href points to an id of an element on the same page.You can direct focus to focusable elements.
<a href="#button">Jump to button</a>
<button id="button">Button</button>

You can also direct focus to non-focusable elements. This feature is unique to links. These four things happen when you direct the focus to a non-focusable element.
<body>.It’s best to show you with an example. Let’s say you have the following HTML:
<button>First Button</button>
<article id="article">
  <h1>The quick brown fox jumps over the lazy dog</h1>
  <p>But the lazy dog refuses to move. It continues sleeping.</p>
  <button>Second Button</button>
  <button>Third Button</button>
</article>
<a href="#article">Jump to article</a>
Here, the link points to #article, but #article is not focusable.
If you click the link, the focus goes to <body>. We know this because document.activeElement is <body>. In the GIF below, I tabbed to the button before clicking on the link. This shows you that focus goes to <body>.

Any keypress after clicking on the link originates from <body>. We can test this with an event listener.
document.addEventListener('keydown', event => {
  console.log(event.target)
})

You can still tab to the next focusable element (in this case, it’s Second Button).

You can also shift-tab to the previous focusable element (in this case, it’s First Button).

We use this feature to let users jump around a page. Here’s an example where I let users jump to a section they’re interested in.

If you focus on an element, the browser will jump to the element. This is true with both Element.focus and links.

If you want to disable the auto-scrolling behavior, you can pass preventScroll: true to Element.focus.
Element.focus({preventScroll: true})
If you want to disable the auto-scrolling behavior on links, you need to use preventDefault. This prevents all default behavior present on links.
const a = document.querySelector('a')
// Don't do this unless necessary
a.addEventListener('click', event => {
  event.preventDefault()
})
In my opinion, you should allow browsers to scroll to the focused element. It doesn’t make sense to focus on an element that’s outside of the viewport.