Skip to content

Commit

Permalink
update a11y
Browse files Browse the repository at this point in the history
  • Loading branch information
redwoodjsbot committed Apr 3, 2022
1 parent 9cc2027 commit b08f390
Showing 1 changed file with 22 additions and 24 deletions.
46 changes: 22 additions & 24 deletions docs/docs/a11y.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,25 @@ A core feature that's built-in and well-supported.

There's a lot of great tooling out there that'll not only help you build accessible websites, but also help you learn exactly what that means.

> **If I use tooling, do I still have to manually test my application?**
> **Does tooling obviate the need for manual testing?**
>
> Unequivocally, yes.
> Even with all the tooling in the world, manual testing's still important, especially for accessibility.
> No—even with all the tooling in the world, manual testing is still important, especially for accessibility.
> But just because tooling doesn't catch everything doesn't mean it's not valuable.
> It'd be much harder to learn what to look for without it.
## Accessible Routing

For single-page applications (SPAs), accessibility starts with the router.
Without a full-page refresh, you just can't be sure that things like announcements and focus are being taken care of the way they're supposed to be.

Here's a great example of [how disorienting SPAs can be to screen-reader users](https://www.youtube.com/watch?v=NKTdNv8JpuM).
On navigation, nothing's announced.
The lack of an announcement isn't just buggy behavior—it's broken.

Normally, the onus would be on you as a developer to announce to screen-reader users that they've navigated somewhere new.
That's a lot to ask, and hard to get right, especially when you're just trying to build your app.
Luckily, if you're writing good content and marking it up semantically, there's nothing you have to do!
The router announces pages on navigation.
That's a lot to ask—and hard to get right—especially when you're just trying to build your app.

The router looks for announcements in this order:
Luckily, if you're writing thoughtful content and marking it up semantically, there's nothing you have to do!
The router automatically announces pages on navigation, and looks for announcements in this order:

1. The `RouteAnnouncement` component
2. The page's `<h1>`
Expand All @@ -44,7 +41,7 @@ more specific usually means more descriptive, and more descriptive usually means

> If you're not sure if your content is descriptive enough, see the [W3 guidelines](https://www.w3.org/WAI/WCAG21/Techniques/general/G88.html).
Even though Redwood looks for a `RouteAnnouncement` first, you don't have to have one on every page—it's more than ok for the `<h1>` to be what's announced.
Even though Redwood looks for a `RouteAnnouncement` component first, you don't have to have one on every page—it's more than ok for the `<h1>` to be what's announced.
`RouteAnnouncement` is there for when the situation calls for a custom announcement.

### `RouteAnnouncement`
Expand Down Expand Up @@ -74,17 +71,18 @@ const AboutPage = () => {
return (
<h1>Welcome to my site!</h1>
// This won't be visible
// highlight-next-line
// highlight-start
<RouteAnnouncement visuallyHidden>
All about me
</RouteAnnouncement>
// highlight-end
)
}

export default AboutPage
```

`visuallyHidden` shouldn't be the first thing you reach for—it's good to maintain parity between your site's visual and audible experience,
`visuallyHidden` shouldn't be the first thing you reach for—it's good to maintain parity between your site's visual and audible experiences.
But it's there if you need it.

## Focus
Expand All @@ -97,8 +95,8 @@ Right now, there's two ways to alleviate this: with skip links or the `RouteFocu

### Skip Links

Since the main content isn't usually the first thing on the page, it's a good practice to provide a shortcut for keyboard and screen-reader users to skip to it.
Skip links do just that, and if you generate a layout using the `--skipLink` option, you'll get a layout with a skip link:
Since the main content isn't usually the first thing on the page, it's a best practice to provide a shortcut for keyboard and screen-reader users to skip to it.
Skip links do just that, and if you generate a layout using the `--skipLink` option, you'll get one with a skip link:

```
yarn rw g layout main --skipLink
Expand All @@ -122,20 +120,15 @@ const MainLayout = ({ children }) => {
export default MainLayout
```

`SkipNavLink` renders a link that remains hidden till focused; `SkipNavContent` renders a div as the target for the link.
For more on these components, see the [Reach UI](https://reach.tech/skip-nav/#reach-skip-nav) docs.

Making sure your navs have skip links is a best practice that goes a long way.
And it really doesn't cost you much!
`SkipNavLink` renders a link that remains hidden till focused and `SkipNavContent` renders a div as the target for the link.
For more on these components, see [Reach UI's docs](https://reach.tech/skip-nav/#reach-skip-nav).

One thing you'll probably want to do is change the URL the skip link sends the user to when activated.
You can do that by changing the `contentId` and `id` props of `SkipNavLink` and `SkipNavContent` respectively:

```jsx
<SkipNavLink contentId="main-content" />

// ...

{/* ... */}
<SkipNavContent id="main-content" />
```

Expand All @@ -149,7 +142,8 @@ So please use this at your discretion—sending a user to an unexpected location

Having said that, if you know that on a particular page change a user's focus is better off being directed to a particular element, the `RouteFocus` component is what you want:

```jsx
```jsx title="web/src/pages/ContactPage/ContactPage.js"
// highlight-next-line
import { RouteFocus } from '@redwoodjs/router'

const ContactPage = () => (
Expand All @@ -158,14 +152,18 @@ const ContactPage = () => (
</nav>

// The contact form the user actually wants to interact with
// highlight-start
<RouteFocus>
<TextField name="name" />
</RouteFocus>
// highlight-end
)

export default ContactPage
```

`RouteFocus` tells the router to send focus to it's child on page change. In the example above, when the user navigates to the contact page, the name text field on the form gets focus—the first field of the form they're here to fill out.
`RouteFocus` tells the router to send focus to it's child on page change. In the example above, when the user navigates to the contact page, the name text field on the form is focused—the first field of the form they're here to fill out.

For a video example of using `RouteFocus`, see the [meetup on Redwood's accessibility features](https://youtu.be/T1zs77LU68w?t=3240).
<div class="video-container">
<iframe src="https://www.youtube.com/embed/T1zs77LU68w?t=3240" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture; modestbranding; showinfo=0" allowfullscreen></iframe>
</div>

0 comments on commit b08f390

Please sign in to comment.