技術ブログのような何か
About | Profile | Application | Source Code | RSS
投稿日時 2025-01-01 21:43:41 +0900 | カテゴリー 技術
前の記事 2024年振り返り | 次の記事 Google Search Console にサイトマップが登録されないけれど気にせず放置している
仕事で Web アクセシビリティについて意識する機会が増えたので、 個人で開発してる Web アプリを Web アクセシビリティの視点で見つめ直してみた。
といっても、自分が Web フロントの改修をしているわけではなく、 同じ部署でアクセシビリティ活動が進行しているので意識することが多いだけ。
Web アクセシビリティについては WCAG(Web Content Accessibility Guidelines)のサイトで説明がある。 日本語訳サイトのWeb Content Accessibility Guidelines (WCAG) 2.2 (日本語訳)があるので、 僕はそのサイトをとりあえず見ている。 また、バージョンが古いがWCAG 2.1 達成方法集というページがあるので、ここも参考にしている。
項目がめちゃくちゃ多いんで、これら全部目をとおして適用しようとするとキツイ。
アクセシビリティを意識するってのは、 具体的には以下の問題を抱えた方々の利用を想定するということ。
色盲の方だと色の区別がしづらい。 弱視や老眼では、小さい文字が読みづらい。 腕に障害があってマウス操作が難しければ、キーボードだけで操作をする。 また、色のコントラストが小さいと普通の人でも見づらい、といった感じだろうか。
これらを踏まえて、自分の Web アプリのbloodborne-build-simulatorを アクセシビリティの視点で確認した。
Windows 11 に標準で搭載されているナレーターを起動する。 ナレーターの起動は Win + Ctrl + Enter で起動する。
目が見えない人になったつもりで、目を閉じてサイトを操作する。 マウスは使えないのでキーボードだけで操作する。 基本は TAB キーでフォーカスを移動する。
ナレーターはフォーカスのあたった要素が何なのか読み上げてくれるので、それを頼りに操作しようとした。 操作したところ、以下の問題に気づいた。
他にも問題はあるはずだが、少なくともこれらの問題に気づいた。
自分が作ったサイトだから勝手がわかってるが、 初めて触る人にはまったく理解できないアプリだろう、と感じた。
前述の気づきのもと、以下の改修をした。
ビルド名はただの text input だが、placeholder が未設定だった。
HTML属性: placeholder - MDNによると、 label の代わりに placeholder を使うのは NG。 期待するデータの種類のヒントになる単語や短いフレーズが適当とのこと。
これを踏まえて「例:上質ビルド」といったテキスト例を placeholder に付与した。 placeholder はスクリーンリーダーで読み上げてくれるので、フォーカス時に例が読み上げられることを確認した。 これで少なくとも何を記述するべきかが明確になった。
前述のビルド名や、各種ステータスの input の説明をどうするべきかは悩んだ。 いわゆる入力フォームであれば label とセットで書くだけで良い。
<label>
ユーザ名を入力してください。
<input type="text" placeholder="例:田中太郎" />
</label>
が、今回のアプリではレイアウトの都合で label を付与するのが難しかった。 そのため代用手段として aria-label を付与した。 aria-label は適切なテキストがなかった場合に使用する属性だ。
メモ: aria-labelは、DOMにラベルとして参照する適切なテキストがない場合に、 対話型要素、または他の ARIA 宣言によって対話するように作られた要素に使用することができます。
前述の「-10」ボタンなどは、最終的に以下のコンポーネントになった。
const IncreaseAndDecreaseButton = ({statusName, currentValue, additionalValue, value, max, text, setValue}: {statusName: string, currentValue: number, additionalValue: number, value: number, max: number, text: string, setValue: Dispatch<SetStateAction<number>>}) => {
const num = Math.abs(value)
const op = 0 < value ? '加算' : '減算'
return (
<button
type="button"
className={buttonClass}
aria-label={`${statusName}の値を ${num} ${op}します。現在の値は ${currentValue} です`}
onClick={e => setValueWithValidation(additionalValue + value, setValue, 0, max)}
>{text}</button>
)
}
例えば「-10」ボタンの場合、フォーカスがあたるとスクリーンリーダーは 「体力の値を 10 減算します。現在の値は 10 です」といった具合に読み上げる。 加算と減算両方のボタンで使用する共通コンポーネントであるため、 操作する値が正負どちらかによって、加算・減算の文章を切り替えるようにした。 これにより、そのボタンを操作すると、何の要素がどう変化するか分かるようになった。
このシミュレータは普段マウスでしか操作してなかった。 そのため、キーボードで操作するまで勝手にフォーカスが外れることに気付けなかった。 勝手にフォーカスが外れるのは意図しない振る舞いだったので、明確な実装ミスだった。
不具合の理由は単純で、UI 全体のコンポーネント内で、コンポーネントを定義していたから。
export default function Simulator() {
// ↓ コンポーネント内でコンポーネントを定義している
const ButtonComponent = () => {
return (
<button>てきすと</button>
)
}
return (
<main>
ほにゃらら
<ButtonComponent />
</main>
)
}
これは全く同じ事例の記事があったため、それを参考に解消した。
コンポーネントをコンポーネント関数の外に移動することで解消した。
const ButtonComponent = () => {
return (
<button>てきすと</button>
)
}
export default function Simulator() {
return (
<main>
ほにゃらら
<ButtonComponent />
</main>
)
}
もともとは共有用 URL を折りたたんだ a タグにしていた。 が、折りたたみ a タグではなく text input にすれば折りたたみが不要だったので、そちらに変更した。 text input に変更したことで label とセットで input の役割を説明できるようになったため、label を付与した。
普段なんとなくで実装していた自分の Web アプリも、 視点を変えるだけでいろんな課題があったことに気づいた。
今回の改修は、自分が気づいた範囲のみの改修であり、全盲の方にはまだ操作しづらいと思う。 しかしながら、改修前よりはずっと親切な作りになったと思う。
今回のアプリは Bloodborne プレイヤーが主なユーザと想定しているため、 目の不自由な方が使うことはほとんどないだろう。 しかし、Web アクセシビリティの勉強のための題材として、 少しずつ改修を続けようと思う。
前の記事 2024年振り返り | 次の記事 Google Search Console にサイトマップが登録されないけれど気にせず放置している