Skip to content

Focus Management

Focus is an important part of keyboard-only and screen reader navigation.

Make sure you set the focus properly on page or context changes. Consider using Reach Router because of the built-in accessibility feature.

From the technical side, we have to assign an invisible focus, so the user can continue the navigation inside this new content.

Example setup:

<body>
<nav><!-- focusable navigation --></nav>
<main>
<!-- more markup with focusable HTMLElements -->
<h1 class="dnb-h--xx-large dnb-no-focus" tabindex="-1">Main Title</h1>
<a href="/path">I'm now focusable on next tab</a>
</main>
</body>

Managing focus state

Make sure you ...

  • set the focus on the content (e.g. <h1 class="dnb-h--xx-large">) after a navigation action, initiated by the user.
  • set the focus into a menu or navigation area, if it has an opening mechanism.
  • also set the focus back to the content, once the menu or navigation area gets closed.

A more complex focus management is already built into the Modal Component. The Modal actually disables focus possibility of the content behind the Modal, so the user only can navigate inside the modal.

Helper tool

The @dnb/eufemia has a built-in helper, to manage basic focus handling. This helper also handles both the tabindex="-1" and the class="dnb-no-focus" situation. So what does it do?

  1. You define on beforehand what should get focus with a css selector (class or id). This (setPageFocusElement) can be set on the very first application start.
  2. Later on, once the focus should be set, you call a second function applyPageFocus. This function will use the beforehand defined selector and execute domNode.focus().

Focus helper

Set focus on a HTML Element, that exists inside the DOM. It can be any HTML Element, no matter if it's an interactive element or not. No interactive elements will be handled by changing the tabindex to 0 alongside a CSS class dnb-no-focus, so no blue focus border is visible.

Simple example:

import { applyPageFocus } from '@dnb/eufemia/shared/helpers'
applyPageFocus('.my-selector')
applyPageFocus('#my-id')

Asynchronous example:

import {
setPageFocusElement,
applyPageFocus,
} from '@dnb/eufemia/shared/helpers'
// 1. Somewhere in your app, set either an element, or a CSS Selector
setPageFocusElement('.css-selector', 'MyCustomName')
// 2. Later you can call this action, once it's time to activate the new focus state
applyPageFocus('MyCustomName', (element) => {
/* optional callback */
})

Skip Link

The @dnb/eufemia also has a small setup for a skip link

Our solution is CSS only and should work for all kinds of application setups. Demo example below:

  1. Place an Anchor with a HTML class .dnb-skip-link like below, as the very first HTML element tag:
<a class="dnb-skip-link" href="#content-id">Skip to content</a>
  1. Define an unique element id, like id="content-id", on your content wrapper:
<body>
<a class="dnb-skip-link" href="#content-id">Skip to content</a>
<header>
<nav>
<!-- Nav links or content to skip -->
</nav>
</header>
<main id="content-id">
<!-- Content goes here -->
</main>
</body>

That's it. The styles are included in both the dnb-ui-basis and dnb-ui-core styling packages.

NB: If you link the anchor to only a <div id="content-id">, then you have to make sure you also add a tabindex.

...
<div id="content-id" tabindex="-1" class="dnb-no-focus">
<!-- Content goes here -->
</div>
...