Global Focus Guidelines
Guidelines
Keyboard navigation of single page apps and large web interfaces can get complicated in a hurry. Use focus management appropriately to guide keyboard users through dynamic UIs.
Many users navigate web interfaces with only their keyboard, tabbing between focusable elements and using arrow keys to navigate interactive widgets such as menus. In dynamic user interfaces, the set of focusable elements on the screen changes as the user interacts with it.
When a user's action causes a UI change, such as an element appearing or disappearing from the screen, we can use focus management techniques to prevent the user from getting lost. When focus management is done right, it helps keyboard and screen reader users discover UI changes and easily reach the next logical step in their flow.
General
- The user's focus should never move without their actions triggering a change.
- If the user's action causes the currently focused element to disappear, move their focus to the next logical place in the UI.
- Ensure that the user can always tell where their focus is on the page. Every focusable element should have a focus style that is visually distinct from its unfocused stated.
- When a user closes a menu, dialog, or other sort of popover component, their focus should return to the element that triggered the display of that component.
Errors
- When the user attempts to save and is presented with an error:
- If there are form element errors, place focus on the first input field with an associated error message. This makes it easy for the user to quickly correct the value.
- If an error popover appears, such as in the Docked Form Footer component, place focus inside the popover.
- If a page-level error appears, place focus on the error message.
- For error toasts, refer to the focus guidelines for Toasts.
Lists and Tables
Component Examples: Data Tables, Setup Assistant, Vertical Navigation, Trial Bar
Removing an item
When a row is removed from a list, via a button or menu on that list item, where to place focus depends on where the item sits within the list:
- First row or any middle row: Place focus on the first focusable element in the next row.
- Last row in the list: Place focus on last focusable element of previous row.
- Only row in the list: Place focus on the list container or any content identifying the list as being empty.
Displaying more items in a list
There are several ways to show more items in a list. The important aspect is to ensure that focus is never lost and that when new items are added, focus continues to move "downhill."
"Show More" / "Show Less" toggle button
Vertical Navigation is a good example of this strategy, as it uses markup for Expandable Sections inline with a list.
- User tabs through the items in the list.
- If there is a "Show More" button, user tabs to this button after the last item in the list.
- Pressing the "Show More" button reveals more items below the toggle, but focus remains on this button.
- Pressing Tab on the "Show More" button moves focus to the first item after the button.
Disappearing "Show More" button
Instead of a "Show More" / "Show Less" toggle, sometimes there may only be a single “Show More” button that goes away when pressed. If this is the case, place focus on the first new item that is added to the list.
Lazy loading or infinite scrolling lists
- If a list loads as a user scrolls down the page, it also needs to load as a user tabs through the items in the list. There should be no hiccups when tabbing through a lazy loading list. It is best to load new items as the user’s focus approaches the end of the list. Don’t wait until they reach the last item, or tab beyond the last item.
- There must be some keyboard mechanism for moving beyond an infinitely loading list. This will prevent a keyboard-only user from getting stuck in a list that "never ends" when they want to move beyond the list. Options include but are not limited to:
- A skip link before the list to take a user to the first focusable element after the list
- A keyboard shortcut to move the user to the first focusable element after the list
Dialogs
Dialogs come in two forms: modal and non-modal:
- A modal dialog is a window that sits above the main application. When it is displayed, the content behind is inactive. The user cannot interact with the content behind the modal until they close the dialog.
- A non-modal dialog is a small application window that sits above the main application. It's displayed and focusable at the same time as the main application. This means that a user can switch back and forth between the non-modal dialog and the main application.
Modal Dialog Examples: Modals, Welcome Mat
Non-Modal Examples: Docked Composers, Notification Card, Panels, Popovers, Trial Bar
Opening dialogs
- The user must initiate the action to open a dialog, by clicking or pressing Enter/Spacebar a button (known as the dialog's trigger).
- When the dialog opens, move focus into the dialog.
- Focus should always be trapped inside the dialog. This means when tabbing from the last item in the dialog, focus goes back to the first item in the dialog.
To determine where focus should go when the modal opens, follow these questions:
- Question 1: Is it a multi-step modal?
- Yes - Is there a subtitle that changes for each step?
- Yes - Focus the subtitle that changes
- No - Go to question 2
- Yes - Is there a subtitle that changes for each step?
- Question 2: Is there a Title inside the modal header?
- Yes - Focus the title inside the modal header
- No - Go to question 3
- Question 3: Are there interactive elements anywhere within the modal body, excluding modal footer (ie. links, buttons, inputs)?
- Yes - Is the first interactive element a tooltip?
- Yes - Focus the close button
- No - Focus the first interactive element
- No - Focus the close button
- Yes - Is the first interactive element a tooltip?
If none of these apply or you have an exception, consult your friendly neighborhood accessibility specialist.
Closing dialogs
- The Escape key should close the dialog. Actions such as "OK," "Cancel," or any other closing buttons may also apply.
- When closing the dialog via one of the above mechanisms, focus must return to the item that triggered the dialog.
- If the dialog was triggered from within a menu, place focus on the menu’s trigger.
- If the trigger no longer exists in the DOM, place focus in a logical place, dependent on the new landscape of the page. An example of this would be deleting a record from a table view. If you choose the "Delete" action from the record's actions menu, you’ll get a modal prompt to confirm deletion. After the deletion, the row and thus the action menu will be gone. In this case, consult our Lists and Tables focus guidelines to learn where to place focus after removing an item.
- If closing a dialog results in a Toast or other confirmation, place focus inside of the toast. When the toast closes, place focus on the element that initially triggered the dialog.
Moving in and out of non-modal dialogs
Pressing Cmd/Ctrl + F6 should move focus between the dialog, other open dialogs, and the application. Consult the Global Orchestration section of these guidelines for more on F6.
Notification cards
Notification cards appear as a series of non-modal dialogs, preceded by a visually hidden DOM element with a defined aria-live
attribute. Updates to the content of the aria-live element will read out to screen reader users.
- When a notification card appears, focus stays put where it is. The text inside the aria-live element should be updated to announce the card's arrival to screen readers.
- Pressing Cmd/Ctrl + F6 will move through the various non-modal dialogs that are open on the screen, and ultimately onto the notification card.
- If there are multiple cards, Cmd/Ctrl + F6 should move focus through the cards.
- From the last card, Cmd/Ctrl + F6 should move focus out of the notification cards and back to the app.
Component Examples: Notification Card
Rich Text Editors
Newly loaded rich text editors should not grab focus.
Component Examples: Rich Text Editor
Toasts
Toasts work like dialogs, but with the attribute role="alert"
. This attribute ensures that their contents are read by screen readers.
Component Examples: Toast
Launching a toast
Toasts may only be launched based on a user action, such as saving, creating, deleting or converting a record. This is because toast components act as dialogs. As dialogs, focus must go into them in order for their contents to be read by screen readers. It would be confusing and inappropriate to move focus into dialog without the user triggering this action themselves.
Exiting a toast
When exiting, focus should go to the item that triggered the toast, such as the button that launched a create dialog.
Multiple toasts
If there are multiple toasts, Cmd/Ctrl + F6 should move focus from toast to toast and then back to the application.
Global Orchestration
For interfaces with a number of alerts, panels, composers, and major sections of the page, focus orchestration at an app-wide level allows the user to easily navigate the application. The industry standard is to use the F6 key for global focus management. For web UIs, combine the F6 key with the Cmd key on Mac or the Ctrl key on other operating systems so as not to conflict with browsers' app-wide keyboard shortcuts. Pressing Cmd/Ctrl + F6 should cycle a user through the following regions in a reliable and consistent sequence:
- Open non-modal dialogs
- Open utility panels
- Open docked composers
- Task notifications
- Toast messages
- Main content
- Split view
When the user presses Cmd/Ctrl + F6 to navigate to the next region, focus should go to the first focusable element in that region if nothing was previously focused there, or to the element in that region that last held focus. Pressing Shift + Cmd/Ctrl + F6 should follow these same rules, but move focus into the previous region instead of the next one.
Page Loads and Refreshes
Depending on how a page is loaded, the placement of focus varies. The guidelines below are based on Salesforce's Lightning UI and may not universally apply to other apps.
- Refresh or direct navigation to URL: Focus goes to the very beginning of the page, before the skip navigation links.
- Global Navigation: When opening an object or record from the global navigation, focus should go to center stage.
- Global Navigation (Console): When choosing a record or object in Console apps, focus should go to the workspace tab for the new item added. When opening a new subtab from a workspace tab, focus should go to the subtab’s tab.
- Vertical Navigation: When choosing an item from a vertical navigation, such as that in Reports, Dashboards, Files, or Chatter, focus should go to center stage for this object.
- App Launcher: When switching applications, focus should go to the very beginning of the page, before the skip navigation links.
- Global Search: When performing a global search, focus should go to the results.
- Skip Links: When clicking on a skip link, focus should be placed where the skip link says it will go, e.g. main navigation, main content area, etc.