Where to Put Focus When Deleting a Thing
TL;DR: When deleting something you should generally move focus to the prior equivalent control or its grouping container.
Why This Is a Thing
Plenty of user interfaces let users delete things that are on the screen. It may be an extra address, a calendar item, a message (the same as dismissing), the “last page” button in a pagination flow, and so on.
The challenge is when the thing that does the deleting is (in) the thing that gets deleted, the keyboard focus goes with it. For keyboard users, screen reader users, and magnifier users, there is a moment where they will not know their position on the screen.
The browser decides where to start when the user next presses Tab
, and it may be the top of the page. The keyboard user is forced to Tab all the way back to where they were. The magnification user may experience a sudden jump if the magnifier is tied to focus or may have to pan around trying to find their position. The screen reader user can use screen reader navigation to navigate to the nearest heading or region where they last were.Of course, if focus styles are poor then all those users have an extra layer of frustration.
How to Deal with This Thing
When the user is deleting from a group of similar things, the simplest thing to do is move them to the previous analogous delete button.
The prior control is often in their viewport or close enough that if the view jumps it should not be as jarring. The control is also something they may have already encountered, providing context for where they are. This is especially handy for screen reader users.
If the user deleted the first in a set, then maybe move the user to the container. If the context is a table, then there may be a scrolling-ready wrapper around the table. That is an easy place to drop a user. For other scenarios, you may need to drop them on a heading or something less ideal but still better than nowhere.
For one-off scenarios, such as dismissing a message, it is on you to manage the focus. Perhaps the safest option is to track what had focus just before the message was dismissed and move the user back there. If it was the page, well, that happens.
There Is a Risk to This Thing
This only works if you drop users onto something that makes sense to them. For screen reader users, it should be something with an accessible name and appropriate role. Moving users to a table row is not ideal, for example.
The thing getting focus should have a useful accessible name. If every button in your table is named “Delete”, that is useless to the screen reader to quickly confirm the thing got deleted. Generally a “Delete” button would have a compound name that identifies the thing being deleted.
Be careful dropping users onto “delete” buttons. There is a risk a user may double-tap the Enter
key. If you are not forcing a user to confirm a deletion (or the user cannot undo it), then you may want to add that feature.
Probably do not rely on :focus-visible
for focus styles. All users benefit from knowing where they are, and :focus-visible
styles are absent unless the user is using their keyboard — voice users, touch users, sighted screen reader users, and so on may not be.
Other Things
If for some reason you are forced to disable controls, then this post applies as if the disabled control were deleted. Also, don’t disable controls.
If you are adding things, put the focus on the analogous added control or grouping container.
Are There Exceptions to This Thing?
Yes.
4 Comments
I was planning on writing a blog post on a similar topic! Thanks for writing this…
This is for focus management when the page “refreshes/repaint the website/element” gets removed is so common on sites. I’ve been calling this a “Focus reset” since it goes to the body.I haven’t investigated it enough yet, but I’ve been playing around with the idea of adding a “Successfully Deleted,” confirmation message. For example, if you delete a product, we can replace it with a message saying “XYZ was deleted,” then we could write code to focus the newly injected message.
In response to .Hi, Giovani!
For example, if you delete a product, we can replace it with a message saying “XYZ was deleted,” then we could write code to focus the newly injected message.
If you present a message, understand that unless that message appears where the now-removed thing was that you run the risk of confusing the user. It may even be a 2.4.3 Focus Order or 1.3.2 Meaningful Sequence issue.
In addition, if you give it focus then the role will matter for the context of the thing that was removed. Deleting a row from a table, for example, is probably not a good fit for this approach (and giving the message a role of
row
and nestedcell
can be even worse).You may want to use a toast-like pattern (a live region with a visual cue) instead.
Great post! Is it ever appropriate to drop the user’s focus on an element that is not focusable?
In response to .Hi, Mike! Thanks!
To your question, third paragraph in the How to Deal with This Thing section:
If the user deleted the first in a set, then maybe move the user to the container. If the context is a table, then there may be a scrolling-ready wrapper around the table. That is an easy place to drop a user. For other scenarios, you may need to drop them on a heading or something less ideal but still better than nowhere.
Leave a Comment or Response