https://zenn.dev/takepepe/articles/improve-a11y-and-testing
これまで、フロントエンドの a11y 改善・テスト拡充にあたり「どのように改善すべきか?どのように書くべきか?」という点がハードルだと感じていました。a11y tree を確認するには、dev tools の隅の隅をつつく必要があり、あまり体験の良いものではなく、気に入ったエクステンションもありませんでした。
Testing Library は「誰もがアクセスできるクエリー」を優先的につかうことを推奨していますが、アプリケーションがはじめから a11y に考慮された作りになっているとは限りません。これらの背景から「data-testid」のような、テスト向け属性に頼るワークアラウンドで乗り切ることも少なくありませんでした。
今年 1 月にリリースされたChrome98 の新機能として「Full page accessibility tree」を dev tools で確認できるようになりました。先日の Google I/O でもセッションがありましたので、詳細は動画をご確認ください。
この拡張により、DOM tree と a11y tree のビューをスイッチできます。「role:"名前"」 による木構造ビューを提供してくれるので、ランドマークや特定 Node が、どの様なアクセシブルネームで識別されているのか即座にわかります。もし、div ばかりで構築したアプリケーションであれば、この a11y tree と DOM がひどく乖離していることでしょう。この a11y tree が意図したものでないなら、改善のときです。
a11y 改善の対象として、問題のコンポーネントをみていきましょう。このコンポーネントは一般的な<Card />
コンポーネントを一覧表示した<CardList />
コンポーネントです
Storybook をコミットしていれば「どこが悪いのか?」を、より鮮明に把握することができます。特定の Story ページに遷移し「canvas tab」を押下、別タブでコンポーネントを確認します(キャプチャ右が別タブで開いた状態)
a11y tree はこの様になっていました。カードリストが、うまくセクショニングできていないことが分かります。
これは、<Card />
コンポーネントが<div>
でマークアップされたことが原因です。div は意味を持たないグループとして扱われるため、そのままでは a11y tree には現れません。
export const Card = ({ id, title, text }: Props) => (
<div className={styles.module}>
<h3>{title}</h3>
<p>{text}</p>
<a href={`/articles/${id}`}>詳細をみる</a>
</div>
);
<div>
タグを<section>
タグに変更することで、Card コンポーネントはセクションとして識別されます。改善されたように見えますが、まだ role と、アクセシブルネームは持っていないため、支援技術によりよいマークアップにはなっていません。
export const Card = ({ id, title, text }: Props) => (
<section className={styles.module}>
<h3>{title}</h3>
<p>{text}</p>
<a href={`/articles/${id}`}>詳細をみる</a>
</section>
);