WAI-ARIA における role 属性を使用する際のプラクティスとして、暗黙のロールを明示しないというものがあります。暗黙のロールとは、HTML の各要素に暗黙的に(明示せずとも)規定されているロールのことです。HTML の各要素には何かしらの WAI-ARIA で規定されたロールが対応しています。例えば、<button> 要素なら button ロール、<nav> 要素なら navigation ロールといった感じです。
暗黙的に持っているロールをあえて role 属性で明示することは、冗長なので避けるべきだとされています。
<!-- bad -->
<button role="button">ボタン</button>
<!-- good -->
<button>ボタン</button>ただし、古いスクリーンリーダーをサポートする目的で暗黙のロールを明示することもあります。HTML と ARIA のマッピングが対応していないことがあるためです。
<ul> 要素の例外
しかし、上記のプラクティスにも例外が存在します。<ul> 要素は暗黙のロールとして list ロールを持っていますが、明示的に list ロールを宣言するべきです。
<!-- bad -->
<ul>
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>
<!-- good -->
<ul role="list">
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>理由は、Safari のみ list-style: none スタイルを指定した <ul> 要素には list ロールが自動的に付与されないためです。このため、list-style: none スタイルを指定した <ul> 要素には list ロールを明示的に指定する必要があります。一般的に、HTML の要素だけを見ても特定のスタイルが適用されているかどうかは判断が難しいので、現在 list-style: none スタイルが適用されているかに関わらず、list ロールを明示的に指定することを推奨します。
VoiceOver でのテスト
実際に VoiceOver を使用して、list-style: none スタイルを指定した <ul> 要素には list ロールが自動的に付与されないことを確認してみます。
<style>
ul {
list-style: none;
}
</style>
<ul>
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>まずは Google Chrome で list-style: none スタイルを指定した <ul> 要素を開きます。
「リスト 3 項目」と読み上げられた後、次の要素に移動すると「りんご 1/3」「みかん 2/3」「バナナ 3/3」とリストのアイテムとして認識されていることがわかります。
続いて、Safari で list-style: none スタイルを指定した <ul> 要素を開きます。
りんご、みかんの要素に移動しても単に文字列が読み上げられるだけで、リストのセマンティクスが失われていることが確認できました。
<ul> 要素に role="list" を指定すると、Safari でもリストのセマンティクスが保たれることが確認できます。
<style>
ul {
list-style: none;
}
</style>
<ul role="list">
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>Safari における list-style: none の 例外の例外
Safari において、list-style: none スタイルを指定した <ul> 要素には list ロールが削除されるルールについて例外が存在します。list-style: none スタイルが適用されていたとしても、<ul> 要素が特定の要素のコンテキストに存在する場合、list ロールが適用されます。
例えば、<ul> 要素が <nav> 要素の子要素である場合、list ロールが適用されます。
<style>
ul {
list-style: none;
}
</style>
<nav>
<ul>
<li>りんご</li>
<li>みかん</li>
<li>バナナ</li>
</ul>
</nav>まとめ
- 一般的には暗黙のロールを明示するべきではない
- しかし、
<ul>要素にはlistロールを明示するべき- Safari において、
list-style: noneスタイルを指定した<ul>要素にはlistロールが自動的に付与されないため
- Safari において、
- ただし、
<ul>要素が<nav>要素の子要素である場合は例外的にlist-style: noneスタイルが適用されていてもlistロールが暗黙的に付与される
