Skip to content

Commit

Permalink
chore(Page): updated a11y docs to new template
Browse files Browse the repository at this point in the history
  • Loading branch information
thatblindgeye committed Feb 5, 2024
1 parent fce5530 commit 0bacd76
Showing 1 changed file with 71 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,30 +3,81 @@ id: Page
section: components
---

The **page** component is used to define the basic layout of a page with either vertical or horizontal navigation. Page layouts are defined using page sections, such as the header, body, and footer of a page. The basic layout of a page depends on whether your page uses vertical or horizontal navigation.
import { Checkbox, List, ListItem } from '@patternfly/react-core';

A page can be combined with many other components, so to create an accessible page, refer to the accessibility recommendations for each component.
## Accessibility

**Keyboard users** should be able to navigate through the masthead of the page and into other interactive elements of the page using **Tab** and **Shift + Tab** to move forward and backward through interactive elements.
To implement an accessible PatternFly **page**:

**Screen reader users** should be able to navigate through and interact with the masthead of the page using the same interactions as keyboard users. Elements of a page that do not have visible descriptive text, such as toggle icons, should have alternative text for screen readers.
- Provide a [skip to content](/components/skip-to-content) if more than one page shares the same heading or sidebar content.
- Give each `nav` element on the page a unique `aria-label`.
- Ensure there is only 1 `main` element on the page.
- Ensure each page section has an `aria-labelledby` attribute linked to a heading element within the section.
- If there is no heading within the section, provide an `aria-label` instead.
- Follow any accessibility documentation for other components used within a page, such as a [breadcrumb](/components/breadcrumb), [notification drawer](/components/notification-drawer), or [navigation](/components/navigation).

Consider using a **skip to content** component on your page so that assistive technology users don’t need to make their way through the entire navigation menu each time they go to another page.
## Testing

## To make a page accessible:
- Use semantic elements when possible, as these will have default roles. If this is not possible, manually add roles to identify different regions of the page as needed.
- If there are multiple instances of one type of semantic element (for instance, two `<nav>` items), label the elements.
- For every element that does not contain text, add an `aria-label` attribute that contains alternative text.
- If using notifications in the masthead, refer to notification badge accessibility guidelines.
At a minimum, a page should meet the following criteria:

The following props/attributes have been added for you or are props/attributes that can be customized:
<List isPlain>
<ListItem>
<Checkbox id="page-a11y-checkbox-1" label="If more than one page has the same header and/or sidebar content, a skip to content is passed to the page." description="This allows users to skip repetitive content, as otherwise they would have to navigate through each heading and sidebar item on every page." />
</ListItem>
<ListItem>
<Checkbox id="page-a11y-checkbox-2" label={<span>If there are multiple nav elements on a page - such as a side navigation, header navigation, and/or breadcrumb navigation - each is given a unique <code className="ws-code">aria-label</code>.</span>} description='This will differentiate the various navigations on a page to a user who is navigating via a rotor menu. Otherwise each element would be announced as something generic such as "navigation".' />
</ListItem>
<ListItem>
<Checkbox id="page-a11y-checkbox-3" label={<span>Only 1 <code className="ws-code">main</code> element exists on the page.</span>} />
</ListItem>
<ListItem>
<Checkbox id="page-a11y-checkbox-4" label={<span>Each page section has an <code className="ws-code">aria-labelledby</code> attribute linked to a heading element within the section, or the section has an <code className="ws-code">aria-label</code> if there is no heading.</span>} description="This provides a more succinct label for the section when a user is navigating via a rotor menu, otherwise the entire content of a page section would be announced." />
</ListItem>
<ListItem>
<Checkbox id="page-a11y-checkbox-5" label="If any other components are used within any page sub-component, those components follow their own accessibility documentation." />
</ListItem>
</List>

| React prop | React component that it should be applied to | Which HTML element it appears on in markup | Reason used |
| -- | -- | -- | -- |
| `aria-label` | PageHeader | .pf-v5-c-button.pf-m-plain | Labels the navigation toggle button |
| `aria-controls` | PageHeader | .pf-v5-c-button.pf-m-plain | Identifies the element controlled by the toggle |
| `mainAriaLabel` | Page | .pf-v5-c-page__main | Labels the main section |
| `mainContainerId` | Page | .pf-v5-c-page__main | An id to use for the [role="main"] element |
| `mainTabIndex` | Page | .pf-v5-c-page__main | A tabIndex to use for the [role="main"] element. Defaults to -1; make this value null to unset it |
| `skipToContent` | Page | .pf-v5-c-button.pf-m-primary.pf-v5-c-skip-to-content | Skip to content component for the page |
| `role` | Page | .pf-v5-c-page__main | Value for the role on the `<main>` element |
## React customization

The following React props have been provided for more fine-tuned control over accessibility.

| Prop | Applied to | Reason |
|---|---|---|
| `mainAriaLabel="[text that labels the main content container]"` | `Page` | Adds an accessible name to the main content container. This should only be passed in when the `mainComponent` defaults to "main" or when the `role` property is also passed in. |
| `mainComponent="[main or div]"` | `Page` | Sets the wrapper element of the main content. By default this will render the `main` element. You should only pass a value of "div" if the page already has a `main` element. |
| `mainContainerId="[id for the main content container]"` | `Page` | Sets the `id` of the main content container. This must be passed in when a skip to content is passed to the page, with the value being linked to the skip to content's `href` property, e.g. `href="#container-id`. |
| `mainTabIndex={-1 or null}` | `Page` | Set the tabindex for the main content container. This must be passed a value of `-1` when a skip to content is also passed to the page, as some browsers require it in order for skip links to work correctly. |
| `role="[role of the main content element]"` | `Page` | Sets the `role` attribute of the main content element. This should only be passed in if the `mainComponent` property has a value of "div". You should also avoid passing `role="main"` and instead use the default `mainComponent` value of "main". |
| `hasOverflowScroll` | `PageBreadcrumb`, `PageGroup`, `PageNavigation`, `PageSection` | Indicates that the component's content causes an overflow scrollbar to render. Passing this property will also set the tabindex of the component to `0` so that it can be focused and scrolled via keyboard. **Required** and should only be passed in when the content's height exceeds the component height, and when there is no other focusable content before the primary content of the component. |
| `aria-label="[text that labels the component]"` | `PageBreadcrumb`, `PageGroup`, `PageNavigation`, `PageSection` | Adds an accessible name to the component. **Required** when the component has the `hasOverflowScroll` property passed in. See our content on [scrollable elements](/accessibility/develop-for-accessibility#scrollable-elements) for further information. |
| `component="[an HTML tag]"` | `PageSection` | Sets the wrapper element of the page section. By default this is the HTML `section` element. Customizing this property may require you to take additional considerations that are dependent on your particular use case. |
| `aria-label="[text that labels the page toggle button]"` | `PageToggleButton` | Adds an accessible name to the page toggle button that controls the sidebar expansion. This should only be passed if the page toggle button contains no text content, such as an icon. |

## HTML/CSS customization

The following HTML attributes and PatternFly classes can be used for more fine-tuned control over accessibility.

| Attribute or class | Applied to | Reason |
|---|---|---|
| `.pf-v5-c-page__main` | `div` or `main` | Sets the wrapper element of the main content. You should only place this class on a `div` element if the page already has a `main` element. |
| `.pf-m-overflow-scroll` | `.pf-v5-c-page__main-breadcrumb`, `.pf-v5-c-page__main-group`, `.pf-v5-c-page__main-nav`, `.pf-v5-c-page__main-section`, `.pf-v5-c-page__main-subnav`, `.pf-v5-c-page__main-tabs`, `.pf-v5-c-page__main-wizard` | Renders an overflow scrollbar to render when the component content's height is larger the the component's height. |
| `aria-label="[text that labels the main content container]"` | `.pf-v5-c-page__main` | Adds an accessible name to the main content container. This should only be passed in when the `.pf-v5-c-page__main` class is on a `main` element or when the `role` attribute is also passed in. |
| `id="[id for the main content container]"` | `.pf-v5-c-page__main` | Sets the `id` of the main content container. This must be passed in when a skip to content is present within the page, with the value being linked to the skip to content's `href` attribute, e.g. `href="#container-id`. |
| `role="[role of the main content element]"` | `.pf-v5-c-page__main` | Sets the `role` attribute of the main content element. This should only be passed in if the `.pf-v5-c-page__main` class is applied to a `div` element. You should also avoid passing `role="main"` and instead use a `main` element. |
| `tabindex="-1"` | `.pf-v5-c-page__main` | Set the tabindex for the main content container. This should only be passed in when a skip to content is also present within the page, as some browsers require it in order for skip links to work correctly. |
| `aria-label="[text that labels the component]"` | `.pf-v5-c-page__main-breadcrumb`, `.pf-v5-c-page__main-group`, `.pf-v5-c-page__main-nav`, `.pf-v5-c-page__main-section`, `.pf-v5-c-page__main-subnav`, `.pf-v5-c-page__main-tabs`, `.pf-v5-c-page__main-wizard` | Adds an accessible name to the component. **Required** and should only be passed in when the component has the `.pf-m-overflow-scroll` class has caused an overflow scrollbar to render, and when there is no other focusable content before the primary content of the component.<br/>See our content on [scrollable elements](/accessibility/develop-for-accessibility#scrollable-elements) for further information. |
| `tabindex="0"` | `.pf-v5-c-page__main-breadcrumb`, `.pf-v5-c-page__main-group`, `.pf-v5-c-page__main-nav`, `.pf-v5-c-page__main-section`, `.pf-v5-c-page__main-subnav`, `.pf-v5-c-page__main-tabs`, `.pf-v5-c-page__main-wizard` | Allows keyboard focus to be placed on the component. **Required** and should only be passed in when the component has the `.pf-m-overflow-scroll` class has caused an overflow scrollbar to render, and when there is no other focusable content before the primary content of the component. |
| `aria-label="[text that labels the page toggle button]"` | `.pf-v5-c-button.pf-m-plain` | Adds an accessible name to the page toggle button that controls the sidebar expansion. This should only be passed if the page toggle button contains no text content, such as an icon. |

## Additional considerations

Consumers must ensure they take any additional considerations when customizing page, using it in a way not described or recommended by PatternFly, or in various other specific use-cases not outlined elsewhere on this page.

### Semantic elements

It is important to use semantic elements whenever possible, as these will have default roles that can be conveyed to users via assistive technologies in various ways.

The page section component, for example, should render a native `section` element in most instances as this will be conveyed as sectioned content when a user navigates the page via screen reader as well as via rotor menu. The page component itself is similar in that in most instances it should render a native `main` element.

In cases where the only option is to customize the underlying element of a page component, keep in mind that you may need to take additional steps to retain as high a level of accessibility as possible. For example, you may need to add a `role="region"` to a page section that renders a `div` element instead of a `section`, unless you are simply using a page section for styling purposes.

0 comments on commit 0bacd76

Please sign in to comment.