シリーズ「アクセシビリティ通信」ではウェブアクセシビリティに関するトピックを取り上げていきます。今回は aria-hidden
属性について取り上げます。
aria-hidden 属性の基本
見出し「aria-hidden 属性の基本」aria-hidden
は、WAI-ARIA で定義されている属性(state)で、要素がアクセシビリティ API に公開されているかどうかを示すことができます。
ある要素に対して aria-hidden="true"
を指定すると、その要素自身と子孫要素はアクセシビリティツリーから除外されます。
これは装飾目的の <img>
要素に alt=""
(空の値)を指定することに似ており、スクリーンリーダー等の支援技術に対して、不要または冗長なコンテンツを非表示にするために使用されます。
ただ、<img>
要素とは異なり、aria-hidden="true"
は指定した要素の子孫要素にも影響が及ぶ(隠してしまう)ので注意が必要です。
このコードを Google Chrome のデベロッパーツールで確認すると、aria-hidden="true"
を指定した要素(Baz)がアクセシビリティツリーから除外されていることがわかります。
aria-hidden="true"
とフォーカス可能な要素
この見出しのリンクaria-hidden="true"
を指定した要素自身がフォーカス可能であったり、その子孫要素にフォーカス可能な要素を含めてはいけません。これは aria-hidden="true"
を指定しても、キーボードなどでフォーカスできてしまい混乱を招くためです。
フォーカス可能な要素としては、<a>
、<button>
、<input>
、<select>
、<textarea>
、<summary>
などの要素、tabindex="0"
や contenteditable
属性を指定した要素などが挙げられます。
この問題を解消するには、フォーカス可能な要素に tabindex="-1"
を指定したり、後述する inert
属性で不活性化するといった方法が考えられます。
aria-hidden="true"
と同様に、アクセシビリティツリーから要素を除外する方法としては以下が挙げられますが、微妙に使用する文脈が異なります。
- CSS の
display: none
およびvisibility: hidden
- HTML の
hidden
属性 - HTML の
inert
属性
順番に確認していきましょう。
display: none
および visibility: hidden
との比較
この見出しのリンクCSS の display: none
および visibility: hidden
では視覚的にも非表示になりますが、aria-hidden="true"
では視覚的には表示されたままになります。
このことから aria-hidden="true"
は、装飾要素として視覚的には表示したままで、アクセシビリティツリーからは取り除きたいときに使用することがわかります。
hidden
属性との比較
この見出しのリンクHTML の hidden
属性では、通常はユーザエージェント(ブラウザ)の display: none
が適用されるので、先ほどと同じく視覚的にも非表示になります。
ちなみに、このユーザエージェントが持つ hidden
属性 の display: none
の指定は、ユーザや開発者の CSS によって簡単に上書きすることができ、例えば [hidden] { display: block; }
と指定すれば、可視化されアクセシビリティツリーにも表示されます。
これらを避けるためには、リセット CSS で上書きされないように明示します。
hidden
属性には、アンカーリンクやブラウザのページ内検索で遷移したときに表示されるuntil-found
というキーワードを指定できるので1、上記のように:not()
擬似クラスを指定しています。!important
ではなく、@layer
を使用して優先順位を指定したほうがスマートかもしれません。
inert
属性との比較
この見出しのリンクHTML の inert
属性では、視覚的には表示され、子孫要素も含めてアクセシビリティツリーから取り除かれる点は aria-hidden="true"
と同じですが、不活性化される点が異なります。
つまり、属性を指定した子孫要素にフォーカス可能な要素(<a>
や <button>
)を含んでいる場合、aria-hidden="true"
の場合は依然としてキーボード操作でフォーカスすることができますが、inert
ではこれらも含めて無効になります。
ただ、inert
を指定した場合、テキスト選択やコンテキストメニュー、クリックイベントなど、すべての操作ができなくなるので注意が必要です。
上記のコードでは、aria-hidden="true"
の子孫要素へのキーボードフォーカスを禁止するために、tabindex="-1"
を指定しています。
続いて、よくある例を取り上げながら aria-hidden
属性の使い方を見ていきます。
例1: インライン SVG
見出し「例1: インライン SVG」まず、もっともよく見られるケースとしては、装飾目的のインライン SVG の要素に対して aria-hidden="true"
を指定する例が挙げられます。
インライン SVG は、拡大縮小しても劣化せず、単純な図形であればパフォーマンスも高いため、ウェブサイトやウェブアプリで使用するケースは増えていますが、装飾目的の場合には aria-hidden="true"
を指定して、アクセシビリティツリーから取り除くのがよいでしょう。
一方で、情報として意味のある画像には aria-hidden="true"
を指定すべきではありません。<title>
要素や aria-label
属性を指定して、支援技術にも情報が伝わるようにしましょう。
なお、SVG コードの最適化については、以下の記事でも説明しています。
例2: ティッカー
見出し「例2: ティッカー」次に、ここ最近のウェブデザインの表現としてよく見られるティッカー(ニュースティッカー、スライダー)について考えてみます。
テキストや画像がスクロールして流れますが、幅全体を埋める必要があるので、同じ要素を繰り返し配置するケースがあります。以下はコードの例です。
このとき「No ARIA is better than Bad ARIA」のテキスト2は 4 回読み上げられます。1 回だけ読み上げてほしい場合には、残りの要素に aria-hidden="true"
を指定します。
要素全体が装飾的な役割しかなく、コンテンツとして読み上げる必要がないときには、親要素に aria-hidden="true"
を指定します。
また、「aria-hidden="true"
とフォーカス可能な要素」でも述べたように、aria-hidden="true"
を指定した要素にフォーカス可能な要素が含まれる場合には、tabindex="-1"
を指定してフォーカスできないように対応しましょう。
WCAG「2.2.2 一時停止、停止、非表示」
見出し「WCAG「2.2.2 一時停止、停止、非表示」」WCAG の「2.2.2 一時停止、停止、非表示(レベル A)」では、以下の達成基準が定められています。
加えて、このページでは以下の説明が記載されています。
このように、フォーカス時の一時停止のみではこの基準を満たすことはできないため、一時停止・再生のトグルボタンを用意するといった対応が望ましいでしょう。
CSS の prefers-reduced-motion
を使用する方法3も考えられますが、設定方法を知らないユーザや、変更が OS 全体に反映されることを望まないケースもあることを踏まえると、一時停止・再開できる機能もあわせて用意するのがより理想的ではあります(開発コストは増えますが)。もちろん、アニメーション自体の必要性についても考える必要があるでしょう。
例3: 文字ごとに区切ったテキスト
見出し「例3: 文字ごとに区切ったテキスト」最後に文字ごとに <span>
要素などで区切ったテキストの例を見ていきます。
例えば、一文字ずつ順番にアニメーションさせたい場合や、文字ごとに罫線で囲ったスタイルを適用したいケースなどが該当します。
この HTML を macOS の VoiceOver で読み上げると一文字ずつ分割されてしまい、「考える」は「こうえる」と読まれてしまうことがあります。
使用する支援技術とブラウザの組み合わせ、指定されたスタイルによって読み上げの結果は異なります。
この問題を解消するには、<span>
要素で区切ったテキストは aria-hidden="true"
を指定してアクセシビリティツリーから除外して、別途読み上げ用のテキストを用意します。
<p class="hero-ja" aria-hidden="true">
<span>ウ</span>
<span>ェ</span>
<span>ブ</span>
<span>の</span>
<span>本</span>
<span>質</span>
<span>か</span>
<span>ら</span>
<span>考</span>
<span>え</span>
<span>る</span>
</p>
<p class="sr-only">
ウェブの本質から考える
</p>
<style>
/* ... */
.sr-only {
position: absolute;
overflow: hidden;
clip: rect(0, 0, 0, 0);
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
border-width: 0;
white-space: nowrap;
}
</style>
また、一文字ずつ <span>
要素で囲うと、Google 翻訳などの拡張機能を使用したときに意図しない翻訳になることがあるので、適宜 translate="no"
を指定するのがよいでしょう。
正しく翻訳されたテキストを提供したい場合には、日英の表記を並べて表示する方法や、属性セレクタ([lang="ja"]
など)を使用して表示を出し分ける方法が考えられますが、その場合には、デザインレベルでの再考が必要になるかもしれません。
おわりに
見出し「おわりに」ここまで、3 つの例を取り上げながら aria-hidden="true"
の使い方について説明しました。そのほかの例としては、スライダー(カルーセル)におけるビューポート外のスライドに対する指定や、アイコンフォントへの指定が考えられそうですます。
あらゆる状況を踏まえて、完璧にアクセシビリティ対応することはほぼ不可能ですが、ウェブアクセシビリティのチェックツールを使用したり、実際にスクリーンリーダーやキーボードのみで操作してみると、アクセシビリティ上の問題に気づくことができます。
これらをひとつずつ改善して積み上げて、より使いやすくアクセシブルなウェブサイトになることを目指していきましょう。
参考文献
見出し「参考文献」本記事の作成にあたり、以下のウェブページを参考にしました。
- aria-hidden | MDN(外部リンクを開く)
- inert | MDN(外部リンクを開く)
- Accessible Rich Internet Applications (WAI-ARIA) 1.2 | W3C(外部リンクを開く)
脚注
-
「No ARIA is better than Bad ARIA」は、「誤った ARIA を使用するぐらいなら ARIA を指定しないほうが良い」という教訓です。用法・用量を守って正しく使いましょう(自戒の念を込めて)。 ↩
-
C39: モーションの防止に CSS reduce-motion クエリを使用する | WCAG 2.1 達成方法集 ↩