Global Focus Guidelines

Global Focus 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

Component Examples: Modals, Welcome Mat

Entering a modal dialog

  • The user must initiate the action to open a modal dialog, by clicking or pressing Enter/Spacebar on the modal dialog's trigger. Once open, the focus must go inside of the modal.
  • Focus should go to the first logical focusable element after the close button, unless the close button is the only focusable element, in which case it should receive focus.
  • 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.

Closing a modal dialog

  • 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 modal 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 modal dialog.

Non-Modal Dialogs

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.

Component Examples: Docked Composers, Notification Card, Panels, Popovers, Trial Bar

Opening a non-modal dialog

  • A non-modal dialog cannot be opened automatically when another element takes focus. To open a non-modal dialog, a keyboard user must navigate to a button and press Enter or Tab to trigger the dialog.
  • When a non-modal dialog opens, it must automatically take focus. Focus should go to the first focusable element inside 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.

Leaving a non-modal dialog

  • When focus is inside the dialog, the Escape key should close the dialog and move focus back to the item that triggered the dialog.
  • 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.