Whilst accessibility means you largely want to steer clear of autofocus on web forms, sometimes it can be beneficial. In HTML, we can now reach for the handy autofocus
attribute, but as I recently learnt that doesn't always do what you expect when dealing with a shadow DOM (in this case, React's equivalent). Daniel's article was by far the best at both describing the issue and offering some solutions, though even here it only works most of the time (Firefox does something which I feel is logical but unfortunately not consistent with either the W3C spec or what most people would want to happen).
So here are the (confusingly more than three) techniques:
- The
autofocus
attribute (😉) forinput
elements that are always present (elements loaded later have some weird cross-browser differences); - The
focus()
DOM API that allows you to select an element using JavaScript and force focus on it i.e.element.focus()
, which works almost always but can be tricky to target correctly (and reliant on client-side JavaScript);- FYI remember that the opposite of
focus()
isblur()
, and both can be handily combo'd withselect()
for some even better UX!
- FYI remember that the opposite of
- The React
autoFocus
prop, which effectively mimics the HTMLautofocus
attribute but only triggers it when a component mounts, helping with the cross-browser issues but meaning that if you mount before visually showing an element it can steal focus incorrectly; - The
useRef
hook, which is effectively just using thefocus()
API within React's own life cycle; - The
useCallback
hook, which does the same thing asuseRef
only with more control. This appears to be the most universal option in React right now.