【Flutter】アクセシビリティが高いアプリを作りたい
はじめに
先日のWWDCでアクセシビリティに関するセッションを視聴したりラボに参加する機会があったのですが、幅広いユーザーが使えるアプリを作っていきたいと思いつつも普段全然意識できていなかったなと反省したので基本的なところから振り返ってざっくりまとめました。
アクセシビリティとは
アクセシビリティは「アクセスしやすい」「近づきやすい」を意味する言葉で、アプリにおいてはあらゆる年齢層・身体能力を持つユーザーでも使いやすいものがアクセシビリティが高いと表現されているように思います。
iOS/Androidの両方で幅広いユーザーに使ってもらうための機能がたくさんあり、たとえば
- コンテンンツの読み上げ
- ズーム表示
- 音声コントロール
- 字幕表示
などがあります。
iOSのアクセシビリティ設定の一部
Flutterがサポートしているもの
アクセシビリティを強く意識せずにアプリを作っても、フレームワークのサポートによってある程度対応できているものがあります。
大きいフォントへの対応
Flutterのテキストウィジェットは、デバイスで設定されたフォントのサイズに基づいて自動的に計算し、アプリに反映させます。
スクリーンリーダーへの対応
スクリーンリーダーとは画面を読み上げる機能のことで、AndroidではTalkBack
、iOSではVoiceOver
をオンにすることで使用できます。
なぜ標準ウィジェットを使うだけでスクリーンリーダー対応ができるかというと、多くのWidgetの内部でSemantics
クラスが使用されていて、Semanticsツリーを形成しているためです。
Semanticsクラスについて
Semantics
はWidgetに説明をつけるためのクラスです。
このクラスでラップして適切なプロパティを設定することでユーザーに必要な情報を届けることができます。
以下はContainer
にラベルをつける例で、スクリーンリーダー機能をオンにしていると「This is a blue container」という音声フィードバックを受け取ることができます。
Semantics(
container: true,
label: 'This is a blue container',
child: Container(
height: 100,
width: 300,
color: Colors.blue,
),
),
標準Widgetではどのように使われているのか見てみます。AppBar
の実装の一部です。
excludeHeaderSemantics
はSemantics
を除外するかどうかのプロパティですが、デフォルトでfalse
になっているので特に何も指定しなければSemantics
を使用してtitle
をスクリーンリーダーに対応させることができます。
Semanticsを関連づけるMergeSemanticsクラス
リンク先のドキュメントにも例として挙げられていますが、チェックボックスとテキストウィジェットが隣どうしに設置されている時、別のものとして読み上げられてしまうとユーザーの混乱を招くためMergeSemanticsでラップして関連付いていることを示す必要がありそうです。
チェックボックスとVoiceOverというテキストは関連付いていて欲しい
不要な情報を除外するExcludeSemanticsクラス
たとえば以下の実装だと必要になってきそうです。
- Stackで複数のWidgetを重ねているけどユーザーに伝えたい情報はごく一部
- 完全に装飾のためだけに存在しておりユーザーに情報を伝える必要のないWidget
以下の動画の8:40秒あたりから、不要なSemanticsが混ざっているアプリをスクリーンリーダーを使って操作している様子が見られます。
画面をはっきりと見ることが難しくスクリーンリーダーが必要なユーザーにとって、伝えたい情報を厳選することが非常に大切なことがわかります。
ちなみに、IgnorePointer
を使用すると子ウィジェット以下のSemacticsは全て無視されるので、こちらは逆に伝えたい情報が含まれている場合はIgnorePointer.ignoringSemantics
をfalseにして有効にする必要があります。
アクセシビリティのテスト
アクセシビリティのガイドラインに対応できているかどうかテストできるmeetsGuideline
が用意されており、以下の項目の確認ができます。
- androidTapTargetGuideline: Androidの最小タップ可能領域のガイドライン
- iOSTapTargetGuideline: iOSの最小タップ可能領域のガイドライン
- textContrastGuideline: WCAG最小テキストコントラストガイドライン
- abeledTapTargetGuideline: ラベル付きタップターゲットガイドライン(タップ・長押しアクションにラベル付けを強制する)
全てのウィジェットをテストするのは難しいですが、共通ウィジェットを作成した時は必ずテストを通過させるようにしたりが良さそうですね。
あとは定期的にスクリーンリーダー機能をオンにして一通りアプリを触ったり、文字サイズを最大にしてちゃんと表示されているか・デザインが崩れていないか・オーバーフローが起きていないか確認するのが一番良さそうな気はします...。
おわりに
Flutterが提供している標準Widgetのおかげで、すでに作ってあるアプリのアクセシビリティ向上のための対応もそこまで工数をかけずにできそうです。(工数をかけてでもやった方がいいかとは思っています)
自分にとっては難しくない操作でも、他の人にとっては難しい操作というものは考えてみればたくさんあるはずで、今後はもっと想像力を膨らませてたくさんの人に楽しんでもらえるアプリ開発をしていけたらいいなと思います📱
Discussion