Skip to content

Accessibility in components

Gavin Barron edited this page Sep 7, 2023 · 2 revisions

New features and components should follow the following accessibility implementation guidelines:

To test your changes use the Accessibility Insights browser extension

  1. Use the Accesibility Insights extension to perform a FastPass scan to detect major issues.
  2. Attempt to use the component with only a keyboard. All interactions available to a user with a mouse should be available when using only a keyboard.
  3. Focus accessibility testing on the MGT components and not on the Storybook shell.

Accessibility guidelines

Where possible use a native html element or corresponding fluent web component for buttons or links. A div with a click handler requires more work than a button to be accessible.
Html elements have semantic meaning, use this whenever possible to convey intent. e.g. don't use an anchor tag as a button.
If you are unsure about the accessibility of a feature or change, ask a maintainer for guidance.

HTML attribute checklist

  • uses aria-label correctly | string: "Login Button", "Megan Bowen" | - meaningful text should provide identifiable labels for screen readers when additional context is needed over the default content

example call button in mgt-person-card:

<fluent-button
  class="icon"
  aria-label=${ariaLabel}
  @click=${this.callUser}
>
  ${getSvg(SvgIcon.Call)}
</fluent-button>

An aria-label should not be used if it has the same content as already provided, e.g. a button with only text

<!-- Don't do this -->
<fluent-button
  class="icon"
  aria-label="Sign out"
  @click=${this.signOut}
>
  Sign out
</fluent-button>

<!-- Do this instead-->
<fluent-button
  class="icon"
  @click=${this.signOut}
>
  Sign out
</fluent-button>
  • uses tab-index/focus correctly | string: "0", "-1" | - components that are interactive should be navigable by tab key control and provide visual focus indicators. Where possible use html elements that provide focus and interactivity by default, e.g. button and a tags. The base styles for mgt components provide a default :focus-visible selector, you should verify that it is visible and if necessary provide some overrides.

example a list-item:

<li
  tabindex="0"
  class="list-item"
  @keydown="${this.onListKeyDown}"
  @focus="${this.onFocusFirstItem}"
  @click=${(e: UIEvent) => this.handleItemSelect(item, e)}>
  ${this.renderItem(item)}
</li>
.list-item:focus-within{
  outline-style: dashed;
  outline-offset: -12px;
}

Note: if an element has a tab index then it should probably have a click handler.

  • provides alt text information | string: "person icon" | - any <img> tag should contain alt text as well. Alt text should be descriptive and may need to be composed using data from Microsoft Graph and a fix string to provide additional context

example (mgt-person):

<img
  title="${ifDefined(imageOnly ? titleText : undefined)}"
  alt=${`${this.strings.photoFor} ${personDetailsInternal.displayName}`}
  src=${imageSrc}
  @error=${() => (this._isInvalidImageSrc = true)}
/>