{
  "id": 9321838,
  "title": "How Browsers Handle Keyboard Focus Navigation with tabindex -1 and aria-activedescendant",
  "url": "https://urgent.news/2026/09/23/how-browsers-handle-keyboard-focus-navigation-with-tabindex-1-and",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-09-23T10:46:08.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/mspk97/how-browsers-handle-keyboard-focus-navigation-with-tabindex-1-and-aria-activedescendant-3ai2"
  },
  "original_language": "en",
  "account": "In the world of web development, custom dropdowns and combo boxes often present challenges when it comes to keyboard navigation. Developers may use tabindex=\"-1\" to make list items focusable programmatically while bypassing the natural tab order, and rely on aria-activedescendant to indicate the currently selected item. However, this approach can lead to unexpected behavior in screen readers and browsers.\n\nWhen debugging issues with keyboard focus, it's crucial to understand how browsers handle tabindex=\"-1\" and aria-activedescendant. These two attributes do not directly control the focused element or its selection indication. Instead, they rely on the browser's internal focus management system.\n\nTo clarify, setting an element's tabindex to -1 makes it focusable through script, even if it's not part of the natural tab order. However, pressing the Tab key will not move focus to such elements. While programmatically focusing a tabindex=\"-1\" element through .focus(), the Tab key will not land on it.\n\nThe aria-activedescendant attribute plays a critical role in assistive technologies. It informs screen readers that a specific element within a container is the active item, keeping the container focused while virtually moving the focus to the referenced element. For this to work, the container element must be keyboard focusable, typically using a tabindex of 0 or inheriting focus from its parent.\n\nWhen a browser handles keyboard focus with tabindex=\"-1\" and aria-activedescendant, it maintains a single focused element in the DOM—the one that receives keyboard events and the native focus ring. The active descendant, indicated by aria-activedescendant, is not itself focused but referenced virtually by screen readers.\n\nSeveral traps can occur when using these attributes:\n- Forgetting to focus the container element. If the container isn't focused, screen readers won't follow the active descendant.\n- Setting tabindex=\"-1\" on active items and calling .focus() on them, which moves actual DOM focus away from the container.\n- Expecting the native focus ring to appear on the active descendant, as it's not focused itself.\n- Handling keyboard events on the wrong element, as they go to the focused container rather than list items.\n\nTo avoid these pitfalls, developers should ensure the container element is focusable and focused, handle keyboard events on the container, update aria-activedescendant to reflect the active item, and use visual styles to indicate focus on the container. This approach, as demonstrated by a custom listbox example, allows for smooth and accessible keyboard navigation in complex widgets.",
  "summary": "Ever been stuck debugging a custom dropdown or a combo box that ignores keyboard focus in weird ways? Maybe you made the list items tabindex=\"-1\" so they’re not in the tab order, and relied on aria-activedescendant to point to the selected item. But then, pressing arrow keys doesn’t update the screen reader’s focus the way you expect. Or worse, the browser’s native focus ring seems to vanish. I…",
  "key_points": [],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}