Skip to content

Files

Latest commit

 

History

History
109 lines (88 loc) · 11.2 KB

Card.mdx

File metadata and controls

109 lines (88 loc) · 11.2 KB

{/* Copyright 2020 Adobe. All rights reserved. This file is licensed to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */}

Card Accessibility Specification

Overview

A Card is a pattern that is commonly used for browsing content as part of a GridView. Cards display custom content, which are generally items a user can buy, own, read, or that a user has saved or created. Cards can be completely custom, or built using some of the components provided out of the box. Typically, cards have a cover photo or preview image at the top, a body with some information about the content, and an optional footer.

WAI-ARIA Design Pattern

There is no <card> element in HTML nor a WAI-ARIA "Card" design pattern to follow. The Inclusive Components project provides a useful example using Cards for a list of blog articles that is worth checking out.

In React Spectrum, Card accessibility depends on the context in which it is used.

On its own, a Card behaves as a generic region, however when rendered as an item in a GridView, which implements the WAI-ARIA 1.1 Layout Grid design pattern, a Card behaves as a row header contained within the item view row.

Keyboard (standalone/static)

  • With a standalone or static Card, that is not rendered within a GridView, interactive descendants of a Card, like the checkbox to select or the action menu button, should be included in the keyboard navigation order for the page.
  • Any elements that fade in on hover, like the checkbox to select or the action menu button, should also fade in when focus enters the Card and fade out when focus leaves the Card.
  • In order for elements that fade in on hover, like the selection checkbox or action menu button in "small" variants, to be navigable using the keyboard, they must have CSS visibility: visible so that they are visible in the DOM.
  • In order to distinguish between the selected state and the selected state when the Card has focus, add the focus visible className .focus-ring to the checkbox, when a Card is both selected and focused.

Keyboard (within a GridView)

When the Card is rendered within a GridView, interactive descendants of a Card, like the checkbox to select or the action menu button, should be included in the keyboard navigation order only for the currently focused item view. In item views that are not focused, interactive descendants of a Card should be excluded from the keyboard navigation order by setting their tabIndex props to -1. The GridView should manage keyboard navigation between Cards in a manner similar to the WAI-ARIA 1.1 Layout Grid design pattern. Each Card behaves as a row header contained within the item view row.

  • ArrowRight: Moves focus to the next enabled item view within the grid, regardless of layout. This ensures that a keyboard or screen reader user can navigate to each item in the collection.
  • ArrowLeft: Moves focus to the previous enabled item view within the grid, regardless of layout. This ensures that a keyboard or screen reader user can navigate to each item in the collection.
  • ArrowDown: Moves focus to the adjacent item view in the row after the currently focused item view that has the largest overlap with the currently focused item view.
  • ArrowUp: Moves focus to the adjacent item view in the row before the currently focused item view that has the largest overlap with the currently focused item view.
  • PageDown (optional): Moves focus down an author-determined number of rows, typically scrolling so the bottom row in the currently visible set of rows becomes one of the first visible rows. If focus is in the last row of the grid layout, focus does not move.
  • PageUp (optional): Moves focus up an author-determined number of rows, typically scrolling so the top row in the currently visible set of rows becomes one of the last visible rows. If focus is in the first row of the grid layout, focus does not move.
  • Home: Moves focus to the first item view in the collection.
  • End: Moves focus to the last item view in the collection.
  • Tab/Shift + Tab: Moves focus through the interactive descendants of the currently focused item view.
  • Space: Toggles selection of the currently focused item view or with focus on an interactive descendant, activates the control, stopping propagation so that triggering the descendant does not also toggle selection.

Roles, States, and Properties

Standalone/static

  • By default, the element that serves as the Card container has role of region.
  • The Card container itself should not be focusable and should not have a tabIndex.
  • By default, when the Card includes a CardBody,
    • if the CardBody has a title prop,
      • the Card container element should have aria-labelledby attribute referencing the element containing the title by id.
      • If the CardBody also has either subtitle or description props, the Card container should have aria-describedby attribute referencing the elements containing the subtitle and/or description by id.
    • If the CardBody does not have a title prop, but does have either subtitle or description props, the Card container should have aria-labelledby attribute referencing the elements containing the subtitle and/or description by id.
  • When the Card allows selection,
    • the checkbox should have a title prop with localized string for Select.
    • To better express the selected or not selected state of the Card, the aria-label prop for the checkbox may be set to a localized string for (Not selected) or (Selected).
    • The aria-labelledby prop for the checkbox should then concatenate the aria-labelledby prop for the Card container element with the id prop for the checkbox, so that the checkbox will be labelledby the CardBody title and a localized string for the current selected state.
  • By default, CardCoverPhoto is presumed to be decorative, however, the alt prop can be used to specify a localized string to serve as alternative text for the image.
  • When alt text is provided, the CardCoverPhoto element will have the role of img and the alt prop should be assigned to its aria-label attribute.
  • In variants where the CardCoverPhoto element has children as well as an alt prop, the CardCoverPhoto element should have the role of group, so that the children will be accessible to assistive technology.

Within a GridView

  • The GridView itself should have role of grid.
    • The GridView should communicate the total number of items in the collection using the aria-rowcount prop.
    • The GridView should communicate the total number of columns in each item using the aria-colcount prop with the value set to 1.
  • Each Card container should have be contained within an element with role of row.
    • Each row within the GridView should indicate its index position within the collection using the aria-rowindex prop.
  • The element that serves as the Card container has role of rowheader.
    • Since each item in the GridView has only one cell, the rowheader, the Card container should indicate the column index using the aria-colindex prop with the value set to 1.
  • Each Card container and the containing row within the GridView should have aria-selected prop of true or false depending on the selected state.
  • A Card container within a GridView should be focusable and should have a tabIndex of 0 when focused or -1 when not focused. If no item in the GridView has focus, all Cards should have a tabIndex of 0.
  • When a row or one of its descendants has focus, interactive descendants should be made tabbable by setting tabIndex to 0 or undefined.
  • When a row or one of its descendants does not have focus, interactive descendants should have tabIndex of -1 so that they are not included in the keyboard navigation order for the document.
  • By default, when the Card includes a CardBody,
    • if the CardBody has a title prop,
      • the Card container element should have aria-labelledby attribute referencing the element containing the title by id.
      • If the CardBody also has either subtitle or description props, the Card container should have aria-describedby attribute referencing the elements containing the subtitle and/or description by id.
    • If the CardBody does not have a title prop, but does have either subtitle or description props, the Card container should have aria-labelledby attribute referencing the elements containing the subtitle and/or description by id.
  • When the Card allows selection,
    • the checkbox should have a title prop with localized string for Select.
    • To better express the selected or not selected state of the Card, the aria-label prop for the checkbox may be set to a localized string for (Not selected) or (Selected).
    • The aria-labelledby prop for the checkbox should then concatenate the aria-labelledby prop for the Card container element with the id prop for the checkbox, so that the checkbox will be labelledby the CardBody title and a localized string for the current selected state.
  • By default, CardCoverPhoto is presumed to be decorative, however, the alt prop can be used to specify a localized string to serve as alternative text for the image.
  • When alt text is provided, the CardCoverPhoto element will have the role of img and the alt prop should be assigned to its aria-label attribute.
  • In variants where the CardCoverPhoto element has children as well as an alt prop, the CardCoverPhoto element should have the role of group, so that the children will be accessible to assistive technology.

v2 Implementation details

The current v2 Card implementation does not completely conform to this spec: see (PR #691)[adobe#691] for a more complete implementation.

Keyboard navigation between Cards in a GridView, is managed by the GridView. The Card component needs to manage focused and selected state based on the props that CollectionView passes through to the item view.

Dependencies

  • CardBody
  • CardCoverPhoto
  • CardPreview
  • CardFooter
  • GridView