Back to Fluentui

FocusIndicator

apps/public-docsite-v9/src/Concepts/Accessibility/FocusIndicator.mdx

4.40.2-hotfix23.6 KB
Original Source

import { Meta } from '@storybook/addon-docs/blocks'; import { FluentCanvas, FluentStory } from '@fluentui/react-storybook-addon';

<Meta title="Concepts/Developer/Accessibility/Focus indicator" />

Focus indicator

Fluent UI components use tabster for focus handling functionality, so that they can be easily integrated with application-level tabster functionality such as delooser and cross-iframe focusing.

Fluent UI @fluentui/react-tabster package defines useKeyboardNavAttribute, createCustomFocusIndicatorStyle and createFocusOutlineStyle to integrate tabster keyboard navigation mechanism seemlesly within Fluent UI.

useKeyboardNavAttribute

Instantiates keyborg and adds data-keyboard-nav attribute to a referenced element to ensure keyboard navigation awareness synced to keyborg logic without having to cause a re-render on react tree.

tsx
function Root() {
  const ref = useKeyboardNavAttribute();
  return <div ref={ref}>{children}</div>;
}
html
<!-- data-keyboard-nav is present when navigating with keyboard -->
<div data-keyboard-nav="">
  <!-- ... -->
</div>
<!-- data-keyboard-nav is not present when navigating with mouse -->
<div>
  <!-- ... -->
</div>

Styling focus indicators

The default focus indicator used in Fluent UI is an outline. However, in some cases more specific focus indicators are necessary depending on the use case and component design. In order to accommodate these requirements, Fluent UI exports two different utilities to style focus indicators:

  1. createFocusOutlineStyle
  2. createCustomFocusIndicatorStyle

Both of the helper functions are powered using the method described above.

createFocusOutlineStyle

The AccordionHeader component uses createFocusOutlineStyle to style the default outline style when focus is detected

<FluentCanvas> <FluentStory id="components-accordion--default" height={260} /> </FluentCanvas>
tsx
import { makeStyles } from '@fluentui/react-components';
import { createFocusOutlineStyle } from '@fluentui/react-components';

const useStyles = makeStyles({
  focusIndicator: createFocusOutlineStyle({
    // selector to be used to decide focus presence: 'focus-within' | 'focus'
    selector: 'focus-within',
    // custom style to be applied with the outline style
    style: {
      outlineOffset: { top: '6px', bottom: '6px', left: '4px', right: '4px' },
    },
  }),
});

function Component() {
  const styles = useStyles();
  return <div className={styles.focusIndicator} />;
}

createCustomFocusIndicatorStyle

⚠️ A bad focus indicator can have serious accessibility consequences and can render your experience unusable by certain user. Please ensure before creating a custom focus indicator that you have gotten the necessary feedback from designers and accessibility experts.

The Link component uses createCustomFocusIndicatorStyle to add a double underlined focus indication style

<FluentCanvas> <FluentStory id="components-link--default" height={150} /> </FluentCanvas>
tsx
import { makeStyles, createCustomFocusIndicatorStyle } from '@fluentui/react-components';

const useStyles = makeStyles({
  focusIndicator: createCustomFocusIndicatorStyle({
    borderBottomColor: 'transparent',
    textDecorationColor: tokens.colorStrokeFocus2,
    textDecorationLine: 'underline',
    textDecorationStyle: 'double',
  }),
});

function Link() {
  const styles = useStyles();
  return <a className={styles.focusIndicator} />;
}