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.

9 Comments

Reply

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 Giovani Camara. Reply

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 nested cell can be even worse).

You may want to use a toast-like pattern (a live region with a visual cue) instead.

Reply

Great post! Is it ever appropriate to drop the user’s focus on an element that is not focusable?

In response to Mike Herchel. Reply

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.

Reply

In React-Aria, we try to make this a bit easier with FocusScope and Collection components, like TableView.

Collections manage focus so that if focus is lost from a cell when the parent row is removed, it will be restored the the same column in an adjacent row. See TableView CRUD and Inline delete buttons Storybook examples.

We use a FocusScope around a Collection and the ActionBar component, that displays when one or more items within the Collection are selected, so that when a user takes action to delete items using the ActionBar, focus will be restored to the Collection, without the developer using the component having to be explicit about where focus should go. You can visit the ActionBar Storybook example to try this out.

Michael Jordan; . Permalink
In response to Michael Jordan. Reply

Michael, my post is talking about when the thing that does the deleting is (in) the thing that gets deleted. In the ActionBar and CRUD cases, the thing doing the deleting is outside the grid.

As you know, the ActionBar example is already moving focus around programmatically within the pattern by responding to arrow keys (as a collection of <div>s roled-up as an ARIA grid). The user must press Tab↹ to move to another control outside the grid (to a pencil icon that gets an “Edit” tool-tip) that appears only when it gets focus, then Tab↹ to go visually backward to an X icon with no tool-tip (which is a delete button and does not close or dismiss this ARIA toolbar that has appeared and oops lost that row), and then when that delete button is activated the toolbar disappears and focus moves back into the grid (but the rows don’t change their values in the demo so I could not immediately tell that anything deleted) at the position of the row that slid up to fill the gap.

So yes, it indeed drops focus in the right spot but it takes a bit of a circuitous set of steps to delete the row. I am certain with a trained audience this overall pattern is fine.

The CRUD example confounded me because when I added a row I could not get focus onto the trash icon that appeared after selecting a row or rows to delete.

However, the inline delete button pattern works as I describe in this post. Though I find the use of ARIA grid roles for a table of read-only data cells that also contain traditionally tabbable controls (buttons and radios) which can only be accessed with arrows to be utterly confounding.

Reply

Hmmm, I would respectfully suggest focusing on the very next focusable thing. This is on the principle that if I might want to delete a series of things, I would then be focused on the next thing I want to delete, which would save me additional tabbing.

In response to Charles Belov. Reply

I address this scenario and the extra key press is weighed against wayfinding and confirmation of action. Do you have evidence or experience or scenarios where this performs poorly? It might be useful for readers to have that contrast.

Reply

[…] read his article, where he elaborates more on how to handle different scenarios and sanity checks needed for this to […]

Leave a Comment or Response

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>