Handle Focus

To make your components accessible to people with disabilities, program them to handle which element has focus and can receive input.

Web browsers are fully navigable with the keyboard using the tab key. For accessibility purposes, users who rely on keyboard navigation need a visual cue to see which element has focus. People with low vision also use screen readers to navigate web pages. Screen readers read aloud the elements on the page, including the element that has focus. As a developer, you need to ensure that when a user tabs through a page, the browser moves focus to the next logical element.

When a user tabs through a page, interactive elements like <a>, <button>, <input>, and <textarea> receive focus automatically. Elements that are not natively focusable, such as <div> or <span>, can use tabindex="0" to receive keyboard focus.

Only 0 and -1 tabindex values are supported. Assigning tabindex="0" means that the element focuses in standard sequential keyboard navigation. Assigning it tabindex="-1" removes the element from sequential keyboard navigation. For more information, see Keyboard Accessibility.

For custom components, focus skips the component container and moves to the elements inside the component.

Let’s look at some code.

In this example, when a user tabs, focus moves from a button element in parent to an input element in child, skipping child itself.

Code output with custom component selected.

To add focus to a custom component, use the tabindex attribute. In the parent template, we set the child component's tabindex to 0 to add the child component itself to the navigation sequence.

Code output with whole custom component selected.

When creating custom components that contain focusable elements, you might find yourself managing tab indexes or setting focus manually on these elements. To manage focus automatically, set delegatesFocus to true.

Let’s say we have a custom component with a button, which behaves like a native HTML button.

Using delegatesFocus enables the following cases.

  • Adds focus to the native button HTML element using coolButton.focus().
  • If you click a node inside shadow DOM and the node is not a focusable area, the first focusable area becomes focused. This is similar to when you click on a label and focus jumps into an input.
  • When a node inside shadow DOM gains focus, the :focus CSS selector applies to the host in addition to the focused element.

Don’t use tabindex with delegatesFocus because it throws off the focus order.