Amplify UI components follow WCAG and WAI-ARIA best practices and guidelines for color contrast, keyboard navigation, accessible labels, and focus management. The intent of Amplify UI is to provide components that are flexible and can be composed into modern, accessible patterns with as few limitations as possible.
Have you found an accessibility bug or limitation? Open an issue so we can take a look!
What's included?
Amplify UI components have some accessibility needs baked in for ease of use. This includes auto-associating labels with form inputs, a default theme with accessible color contrast, and the flexibility to enhance components to create your own accessible patterns.
Accessible form fields
Form Labels
All of Amplify UI's form field components require passing a label to the input. If an ID is not supplied for the component, one is autogenerated for you so that the label can be programatically associated with the input.
import { Grid, TextField } from '@aws-amplify/ui-react';
export const LabelInputExample = () => (
<Grid
gap="var(--amplify-space-large)"
templateColumns="repeat(auto-fill, minmax(280px, 1fr))"
>
<TextField label="Example text field" />
<TextField
label="Example text field (with custom ID)"
id="custom-input-id"
/>
</Grid>
);
One use case for passing your own custom id to the field is if you need to target it for testing.
Web standards
Amplify UI also follows web standards as much as possible for our components, including relying on native web controls. For example, our CheckboxField is styled to match our default theme, but still uses an <input type="checkbox" />
as the base component.
import { CheckboxField } from '@aws-amplify/ui-react';
export const CheckboxExample = () => (
<CheckboxField label="Example checkbox" name="example" value="yes" />
);
Themeable design tokens
Amplify UI uses design tokens for the color palette, which makes modifying the theme to meet your own color contrast goals more manageable. Amplify UI also provides tokens for properties such as border width and font size if you need to make your own customizations for higher contrast requirements.
The example below shows how to use Theming to supply higher contrast text and border styles.
import { ThemeProvider, Card } from '@aws-amplify/ui-react';
export const ThemeExample = () => {
const theme = {
name: 'high-contrast',
tokens: {
colors: {
font: {
primary: { value: '{colors.black}' },
},
},
components: {
card: {
outlined: {
borderWidth: { value: '{borderWidths.large}' },
borderColor: { value: '{colors.black}' },
},
},
},
},
};
return (
<ThemeProvider theme={theme}>
<Card variation="outlined">Example Card</Card>
</ThemeProvider>
);
};
Enhanceable primitives
Since Amplify UI supports passing down HTML and ARIA attributes to primitive components, it's possible to create your own accessible patterns. The following example shows how to use a View component as an HTML nav
element and how to add a unique name to the nav
element using an aria-label
attribute.
import { View } from '@aws-amplify/ui-react';
export const NavRoleExample = () => (
<View as="nav" aria-label="Component navigation">
Example nav element with aria label.
</View>
);
The next example shows how we can add an aria-live
attribute to our Badge component to announce when the value is updated.
import { Flex, Button, Badge } from '@aws-amplify/ui-react';
import { useState } from 'react';
export const AriaLiveExample = () => {
const [count, setCount] = useState(0);
function handleClick() {
setCount(count + 1);
}
return (
<Flex>
<Button onClick={handleClick}>Add card to list.</Button>
<Badge aria-live="polite" alignSelf="center">
{`${count} cards in list`}
</Badge>
</Flex>
);
};