Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTML link does not get focus outline on receiving focus unless textarea has been focussed explicitly

Example 1 - No focus outline for link

I have a keydown handler for a <textarea>. When the handler gets invoked, I want a link (<a> tag) to receive focus. If you run the example below, click on the textbox with mouse, then type something in the <textarea>, you will see the link receiving focus after 1000 ms (1 second). The link changes its color to green when it receives focus.

But when the link receives focus, it does not get a focus outline around it. I confirmed this with Firefox v143 and Chrome v140.

let link
let text

function main() {
  link = document.getElementById('link')
  text = document.getElementById('text')
  text.value = ''
  text.addEventListener('keydown', keydown)
}

function keydown() {
  setTimeout(handler, 1000)
}

function handler() {
  console.log('text.value:', text.value)
  link.focus()
}

window.addEventListener('load', main)
a:focus { color: green }
<textarea id="text"></textarea>
<a id="link" href="https://example.com/">example.com</a>

Example 2 - Successful focus outline for link

But in the example below, when I type something into the <textarea>, the link gets focus after 1000 ms (1 second) and the link gets an outline too.

Note that in this example, the <textarea> already has focus via text.focus() in JavaScript. So unlike in Example 1, we did not need to click on it with mouse.

The only difference between the previous example and this example is that this example has text.focus() call which the previous example does not have.

let link
let text

function main() {
  link = document.getElementById('link')
  text = document.getElementById('text')
  text.focus()
  text.value = ''
  text.addEventListener('keydown', keydown)
}

function keydown() {
  setTimeout(handler, 1000)
}

function handler() {
  console.log('text.value:', text.value)
  link.focus()
}

window.addEventListener('load', main)
a:focus { color: green }
<textarea id="text"></textarea>
<a id="link" href="https://example.com/">example.com</a>

Question

Why does the link NOT get a focus outline around it in the 1st example and why does it get a focus outline in the 2nd example? I am unable to find anything in the W3 specs that would explain this behavior. Can you help explain this behavior?

like image 869
Lone Learner Avatar asked Nov 14 '25 15:11

Lone Learner


2 Answers

Both example 1 and example 2 behaves the same way.

Load either example, click on the text box with your mouse, and press a letter.

Result: no focus outline

Using the keyboard, make the Textbox the focus

(Shift-Tab will move the focus backwards, from the link, to the text area)

Now press a key

Result: Link has focus outline

If you are not convinced goto Top and do it again :)

If you want the mouse focus to behave the same as the keyboard in Firefox there is an option in about:config. Set browser.display.show_focus_rings = true. Set to true, will make focus outline on the link behave the same, no matter if you use the mouse, keyboard or if you programmatically set the focus to an element.

I believe this "feature" was implemented as part of Firefox accessibility features, and is only triggered (by default) when focus is set programmatically or with the keyboard.

This is not a javascript feature.

Hope this explains the behaviour.

**** Additional Information ****

Was doing some more research to help explain the behaviour more. I came across this article from the W3C Group (The World Wide Web Consortium) in the Web Accessibility Initiative, and they explain it a lot better then I can.

There is also this youtube video that some may find useful that explains feature 2.4.7 Visible focus for focusable elements (AA)

MSDN Documentation can be found here the feature you are looking for is 2.4.7

You can also search focus-visible in google, and there many more documents that give you wants to control the border with css etc.

There is many many many more resources that discuss the requirements set out in the standards document Web Content Accessibility Guidelines (WCAG) 2.2 and the reasons behind these requirements. The feature you are asking about is 2.4.7, a simple search in google, should give you ample information to satisfy any question you have.

like image 74
Luke Attard Avatar answered Nov 17 '25 07:11

Luke Attard


Browsers hide the focus outline after mouse interactions to avoid showing outlines when they aren't needed, but they display it after keyboard or programmatic focus since keyboard navigation relies on a visible indicator for accessibility.
In Example 2:

  • When the page loads, your JavaScript calls text.focus(). Although programmatic, this is interpreted by many browsers as equivalent to keyboard-initiated focus.

  • When you type and later call link.focus(), the browser senses the user's interaction as keyboard-like.

  • The outline appears - UA treat it as :focus-visible

https://drafts.csswg.org/selectors-4/#the-focus-visible-pseudo - "User agents can choose their own heuristics for when to indicate focus"

like image 34
zucker Avatar answered Nov 17 '25 08:11

zucker