Svelte Accessibility warnings 補足資料(2024-02-21)
https://gyazo.com/c33e46be44807f962107a5696515bd99
Programmatic access to the WAI-ARIA 1.2 Roles Model. This package tracks the W3C Recommendation (last update: 6 June 2023). role=genericでaria-labelつけられなくなったみたいに
a11y-accesskey
accessKey属性を使用しない
<a href="https://example.com/" accessKey="U">Example Domain</a>
MacOSだとControl+Optionと特定のキー 妥当+1.icon
a11y-aria-activedescendant-has-tabindex
aria-activedescendantを使用する場合はtabindex属性を使用する
妥当+1.icon
特にtabindexの値は関係なさそう
code:js
// aria-activedescendant-has-tabindex
if (
name === 'aria-activedescendant' &&
!is_dynamic_element &&
!is_interactive_element(node.name, attribute_map) &&
!attribute_map.has('tabindex')
) {
push_warning(attribute, 'a11y-aria-activedescendant-has-tabindex');
}
a11y-aria-attributes
<meta aria-hidden="false" /> <!-- aria属性は使えない -->
妥当+1.icon
ありがたいですね
a11y-autofocus
autofocusを使用しない
ブラウザによっては挙動が異なる、支援技術を使っている場合読み上げで混乱する可能性がある 妥当+1.icon
ただし<dialog>においてのみ例外として捉えていきたい
ブラウザは自動的に<dialog>内の最初にフォーカスされるインタラクティブ要素にフォーカスされる
もし先にフォーカスさせたい要素がある場合はautofocusを提示しておく
参考
<dialog>の中だけは警告を出さないようにルール変えられないかなyamanoku.icon a11y-click-events-have-key-events
クリック以外の操作ができないため
on:keypressやon:keydownなどを併せて使用する
妥当+1.icon
<button type="button">
a11y-distracting-elements
気が散るような要素が使われていないかを確認する
含まれる要素
<marquee>...横移動する
<blink>...点滅する
妥当+1.icon
こうした表現はCSSでできるけど、気が散る可能性はありますね 見た目表現をHTMLで表現するのは避けていきたいyamanoku.icon a11y-incorrect-aria-attribute-type
妥当+1.icon
true/falseが文字列としてなのかBoolean値なのかの違い
論理属性(Boolean attribute)という属性そのもので値自体不要なものもある
値が存在しない場合は空文字("")ではなくundefinedにしておく必要もある
列挙型属性といってtrue/false以外の値を含む場合もあったりする
a11y-interactive-supports-focus
code:html
<div role="button" on:keypress={() => {}} />
妥当+1.icon
a11y-click-events-have-key-eventsと同じ感想
a11y-misplaced-role
roleを指定できない要素にrole指定された場合に指摘してくれる
対象
const invisible_elements = ['meta', 'html', 'script', 'style'];
妥当+1.icon
<svelte:head>の中で書く場合に間違わないようにアリかも
<link>も含めて良さそう
変数としての対象に含めていいかは別ですが<label>とかもダメだったりします
a11y-misplaced-scope
scope 属性は、<th> 要素でのみ使用する
かなり珍しいルール
見出しの対象範囲を指定する
col, row, colgroup, rowgroup
かつては<td>でも使用できていた
妥当+1.icon
a11y-missing-content
見出し要素(h1、h2 など)とリンク要素に対し、コンテンツを持つように強制する
code:html
<!-- A11y: <a> element should have child content (<a>要素は子コンテンツを持つべきです) -->
<a href="/foo" />
<!-- A11y: <h1> element should have child content (<h1>要素は子コンテンツを持つべきです) -->
<h1 />
妥当+1.icon
見出しやリンクをaria-labelで意味づけしていると辿れないことがある a11y-mouse-events-have-key-events
on:mouseover や on:mouseout に対し、それぞれ on:focus と on:blur を付けることを強制する
妥当+1.icon
ツールチップはpopoverで表現してみてもいいかも(要挙動チェック)
code:html
<button type="button" popovertarget="popover-content" popovertargetaction="show">
Show popover
</button>
<div id="popover-content" popover>Popover content</div>
a11y-no-interactive-element-to-noninteractive-role
非インタラクティブな role:article、banner、complementary、img、listitem、main、region、tooltip 妥当+1.icon
そもそも妥当なHTML要素を使用するようにしましょう 一時的にそうせざるを得ない状況もあるかもですが、TODOコメントよろしくいずれは直していったほうがいい a11y-no-noninteractive-element-interactions
妥当+1.icon
期待されうる挙動ではない
インタラクティブな要素と同じように実現するには徒労感が半端ない
そもそも妥当なHTML要素を使用するようにしましょう a11y-no-noninteractive-element-to-interactive-role
button、link、checkbox、menuitem、menuitemcheckbox、menuitemradio、option、radio、searchbox、switch、textbox
妥当+1.icon
そもそも妥当なHTML要素を使用するようにしましょう a11y-no-noninteractive-tabindex
妥当+1.icon
インタラクティブなroleであれば問題なし
それよりも妥当なHTML要素を使用するようにしましょう ちなみに<dialog>では使用禁止です
a11y-no-static-element-interactions
clickをもつ静的な要素にはroleが必要になる
<div on:click={() => ''} />
妥当+1.icon
押せるかどうかが見た目以外で判断できないので
やっぱり妥当なHTML要素を使用するようにしましょう a11y-positive-tabindex
tabIndex属性に1以上の数値を入れないようにする
妥当+1.icon
要素が期待されるタブの順序から外れてしまい、キーボードユーザーに混乱を招くことになります。 書いてあるとおり
0 ... フォーカス可能なだけでフォーカス順序は指定されていない
-1 ... フォーカス可能だが、一度外れるとJS操作以外でしか戻すことは出来ない a11y-role-has-required-aria-props
role を持つ要素は、その role に必要な属性をすべて持つ必要がある
妥当+1.icon
忘れないように教えてくれて助かります
a11y-role-supports-aria-props
明示的または暗黙的な、定義された role を持つ要素は、その role がサポートする aria-* プロパティのみ使用する
妥当+1.icon
誤った指定を避けられるので助かります
a11y-unknown-aria-attribute
妥当+1.icon
助かります
a11y-unknown-role
妥当+1.icon
助かります
a11y-hidden
一部の要素ではaria-hiddenの使用しないようにする
具体的にどういうのがダメなのか?
code:js
if (name === 'aria-hidden' && regex_heading_tags.test(node.name)) {
push_warning(attribute, 'a11y-hidden', node.name);
}
疑問?.icon
見出しは基本あるべきだとは思うけど…
ARIAの操作自体をコンパイラから強制されるべきだと思っていないyamanoku.icon 併せて使ってはいけないroleやARIAと対応する分には良いと思う
a11y-img-redundant-alt
img の alt 属性に、image、picture、photo という単語を含めない
疑問?.icon
適当に付けられるのを避けたいのはわかるけど…
そういう表現をしたい人にとっては別に含めてもいいでしょうyamanoku.icon むしろ避けてaltを空にしてしまっているほうが問題があったりする
code:js
if (/\b(image|picture|photo)\b/i.test(alt_attribute)) {
push_warning(node, 'a11y-img-redundant-alt');
}
a11y-invalid-attribute
<a>要素のhrefの値が空、#、javascript:にしてはならない
疑問?.icon
javascript:は良いと思う
<button>でやれ案件
他は厳しすぎないだろうか?
空の場合は現在のページ自体に飛ぶ
a11y-label-has-associated-control
ラベルとコントロールの関連付けがされているかをチェック 疑問?.icon
<label>C <input type="text" /></label>はわかる
問題は<label for="id">B</label>としているパターン
値のないfor属性だけでもコンパイルは通ってしまう <label for>B</label>でもOK
以前この状態についてを指摘したことがあります
a11y-media-has-caption
mutedでミュート指定しているなら不要
疑問?.icon
疑問というか、惜しいというか…
code:html
<video>
<source src="movie.mp4" type="video/mp4">
<track kind="captions" srclang="ja" lang="ja" src="movie-ja.vtt" label="日本語">
<track kind="captions" srclang="en" lang="ja" src="movie-en.vtt" label="English">
</video>
字幕データ自体も必要
もちろん中身が正しいかもあるが、trackを入れて終わりにだけはしたくない
a11y-missing-attribute
要素にとって必要な属性が入っていることを強制させる
妥当+1.icon
<html> には lang が必要
読み上げや翻訳変換で影響
<img> には alt が必要
<iframe> には title が必要
<object> には title、aria-label または aria-labelledby が必要
疑問?.icon
<a> には href が必要
リンク要素として扱わない場合、この形にしておくのは問題ない spanと同じようなものだと思っていただけるとよいかも
code:html
<ul>
<li><a href="/">TOP</a></li>
<li><a aria-current="page">現在のページ</a></li>
</ul>
<area>にはalt、aria-label または aria-labelledby
hrefがないものには名前付け禁止(aria-label または aria-labelledbyをつけてはならない)
a11y-no-redundant-roles
すでに要素に存在するroleに冗長にroleをつけるのを禁止する
code:ng.html
<button type="button" role="button" />
対象要素一覧
疑問?.icon
支援技術によってはそのroleがないと対応できない場合もある かつては<li>のスタイルをイジるとリストアイテムと認識できないこともあったので意図的につけていたこともある
その旨を受けて<ul>, <ol>, <li>については非対応にはなっている
必要かどうかを議論しつつ都度対応が必要になってくる
現状<search role="search">は特に対象になってない(支援技術へのサポートがまだ) 仕様に従う意味では正しいが、ユーザーのことを想定すると過剰な気もする a11y-structure
特定の子要素を使用する場合にその中に含まれているか
疑問?.icon
code:js
if (node.name === 'figcaption') {
if (!is_parent(node.parent, 'figure')) { push_warning(node, 'a11y-structure', true);
}
}
code:js
if (node.name === 'figure') {
const children = node.fragment.nodes.filter((node) => {
if (node.type === 'Comment') return false;
if (node.type === 'Text') return regex_not_whitespace.test(node.data);
return true;
});
const index = children.findIndex(
(child) => child.type === 'RegularElement' && child.name === 'figcaption'
);
if (index !== -1 && index !== 0 && index !== children.length - 1) {
push_warning(childrenindex, 'a11y-structure', false); }
}
figcaptionだけじゃねーか!!!!!!
ul > li とか…そういうのも...