Yesterday, I looked at trapping focus within an element such that a user couldn't use keyboard-based navigation to tab outside of the given element. That kind of technique would be helpful in a modal window scenario where you don't want the active-focus to leave the modal. However, if the user closes the modal window, we would like to return focus to the previously-active element so that the user can pickup where they left-off in their workflow. We can use the
NOTE: A much more robust example of this technique can be seen in Inclusive Components by Heydon Pickering. This post is just me trying it out for myself.
document.activeElement is a read-only property that contains the DOM (Document Object Model) element that currently has focus. We cannot assign a value to this property; however, if we call
.focus() on another element within the DOM, we will implicitly cause said element to be assigned to the
In a modal window scenario, where we are drawing focus away from the "trigger" element and into the modal window context, we can use the
document.activeElement property to record which element triggered the modal. And then, when the user subsequently closes the modal window, we can call
.focus() on our recorded value to restore focus the previously-active element. This will make Tab-based navigation around the DOM much more fluid and accessible.
button elements that all trigger a single modal window. And, when the user closes the modal window, I'm going to restore focus to the original
NOTE: For the sake of simplicity, I am not including the focus-trapping technique from yesterday's post. This demo is intended to isolate the use of the
As you can see, I have a global variable -
previousElement - that stores the
document.activeElement value at the time the modal window is opened. Then, when the user closes the modal window, I'm simply calling
.focus() on this reference before unsetting it. This returns focus to the original trigger where the user can continue to Tab-navigate through the document.
previousElement variable as it consumed in the modal-window workflow:
As you can see, whenever the user opens and then closes the modal window, focus is returned to the trigger button. And, the user can continue to tab-through the buttons from whence they left-off.
In this demo, I'm exaggerating the
:focus state of elements to make it super obvious where the user's focus is located. However, this kind of focus-restoring workflow really illustrates just how critical it is to have some sort of indication as to what has focus. I'm so embarrassed, in retrospect, at all the times I've set
outline:none because having an outline didn't "fit with our design". So shameful.
Want to use code from this post? Check out the license.