🚥

markuplintのWAI-ARIA向けルールとこれから

2020/12/14に公開1

2020年Webアクセシビリティアドベントカレンダー14日目の記事です。

先日HTMLリンターであるmarkuplintのバージョン1.3.0をリリースしました。今回追加された機能は主にwai-ariaというリントルールの追加で、WAI-ARIAARIA in HTMLにおける role属性やaria属性に関するチェックをするルールです。

wai-ariaルールは次の場合に警告します。

  • 仕様に存在しないロールを指定した場合
    <div role="foobar"></div>
    <!-- foobarというロールは存在しない -->
    
  • 抽象ロールを指定した場合
    <div role="select"></div>
    <!-- selectは抽象ロール -->
    
  • 指定したロール(もしくは暗黙のロール)が持たないステート/プロパティを指定した場合
    <button aria-checked="true">Check me</button>
    <!-- buttonロールはaria-checkedを持たない -->
    
  • ステート/プロパティに無効な値を指定した場合
    <button aria-pressed="on">Push me</button>
    <!-- aria-pressedの値は true/false/mixed の3つ -->
    
  • ARIA in HTML の仕様における要素に許可されていないロールを指定した場合
    <img src="path/to" alt="The Holiday Sale!!" role="banner" />
    <!-- img要素にbannerロールは許可されていない -->
    
  • ARIA in HTML の仕様における要素の暗黙のロールを明示的に指定した場合
    <body role="document"></body>
    <!-- body要素は暗黙のdocumentロールを持つ -->
    

仕様上許可されていない値や組み合わせが警告されるため、つまり無意味だったり無効になる値や組み合わせを見つけることができます。たとえばスペルミスや打ち間違えのようなタイポに気づくことができたり、仕様を勘違いして覚えていた際に最低限気づかせてくれるルールとなります。

ARIA無しのほうが、悪いARIAよりも良い

さてしかしですよ。この程度の機械的チェックじゃあまだまだWAI-ARIAを攻略できません。

WAI-ARIAオーサリング・プラクティスで「ARIA無しのほうが、悪いARIAよりも良い(原文: No ARIA is better than Bad ARIA)」と説明されているとおり、許可された値や組み合わせを用いたとしても悪いARIAを作り出せてしまう可能性があるからです。

なので、今後は次のような別のルールを順次追加してくつもりです。

任意のロールの設定禁止

たとえば「role="button"を使うならbutton要素を使え。role="link"を使うならa要素を使え。」というルールです。オプションで禁止リストを変更できるようにしようと思います。

内容が存在する要素へのaria-label等の禁止

要素内にテキストもしくは認知可能な内容が存在しているにも関わらずaria-labelaria-labelledbyなどで上書きをすることを禁止します。内容やaria-labelなどの優先順位の計算方法はAccessible Name and Description Computation(通称Accname)で定義されていますが、内容があるにも関わらずaria-labelで上書きをしてしまう状態は、見た目と読み上げの差異を発生させたり、開発者の単純な実装ミスの可能性もあります。

aria属性にまつわるアレヤコレヤ

まだまだ調査しきれていないですが、aria-expandedのよくある間違い / masuP.netのようなaria属性の適切な指定や組み合わせ(aria-controlsの参照だったり)などもリンターで問題を見つけて修正を促せるようにできればと思っています。HTMLだけを静的に解析するので限界はありますが、そのあたりは柔軟に見つけていこうかと思います。


markuplintはあくまでもリンターという立ち位置なので、開発者が「絶対に使っちゃいけないということはないが、ほとんどの場合失敗するから辞めておけ」と思っているものはルールで縛れるようにしたいと考えています。もちろん「これはやっていいものだ」と思えばそのルールだけ無効に、もしくはある要素ツリーの範囲内だけ無効にすればよいだけです。

UA/支援技術のバグもしくは非サポートに対して

各種UA/支援技術のWAI-ARIAへの対応は発展途上です。もしくは開発者が古いブラウザや支援技術に対応する必要があるかもしれません。

仕様上有効なはずなのにブラウザが対応してない・スクリーンリーダーが対応していないので現実的に実装できないという問題や、支援技術側の振る舞いはそもそも仕様そのものがなく各ベンダーによって差異があります。そのあたりの情報を集め、警告や修正案を提供できるルールも作りたいと考えています。

これは僕がWebアクセシビリティ基盤委員会 作業部会2(実装)(以下WG2)に参加(現時点はオブザーバー)している理由で、WG2で収集・提供しているアクセシビリティ サポーテッド(AS)情報をAPI化してmarkuplintに利用したいのです。(もちろん、その他のツールでも利用できるようにすることが個人的な目的です)

海外のサポーテッド情報であるAccessibility Supportにも連絡はしていて、ここの情報も利用できないか検討してもらっています(関連Issue)。

分かる人にかしか分からないと思いますが、Can I useというブラウザサポート情報を元にbrowserslistというNode.jsモジュールが存在していて、それをBabelやPostCSS、ESLintが利用してますが、それに似た関係です。

アクセシビリティチェックツールの乱立について

ここ数年でアクセシビリティに関するチェックツールが多くなってきました。今回のアドベントカレンダーでもacotが紹介されてますし、今年発表された現役高校生が作成したvisibleも話題になりました。

ちょっとだけお気持ちを。「乱立マジで最高、いいぞもっとやれ」です。

一見すると「あーなんか似たようなのまた生まれてるなー」だったり「どれ使ったらいいのかわからんくなるやんけー」ってなってしまうものですが、よく見るとそれぞれ役割や利用シーンが異なります。もちろんチェック内容が被ることもあるかもしれませんが、チェックされずに世の中にそのページやアプリがリリースされて誰かが困るより100倍マシです。

で、markuplintはどの立ち位置にいあるかというと、初手で間違いに気づくことを目標としています。最優先している利用シーンはテキストエディタ上です。開発者がタグもしくは属性を入力した瞬間に警告することを最も重視しています。acotやvisible、axe™Nu Html Checkerに比べたらチェックできる内容は少ないかもしれませんが、開発者がマークアップをしてから間違いに気づいて修正するまでの時間をコンマ1秒でも早くするのが目的です。

ここの感覚が早ければ早いほど、「マークアップは難しくない」「WAI-ARIAは難しくない」と感じてもらえると信じています。マークアップは簡単だと思われるのはそれはそれでアレですが、少なくとも間違える恐怖感や不安感は軽減できると思っています。

エディタ上ではmarkuplintが最低限のチェックをし、コーディング中のブラウザ上ではaxe™を、CI上ではacotやvisibleを、という幾重のチェックを通す、そんな開発環境が理想的なのではと思っています。


まだまだ追加したいルールはたくさんありますし、「こういうのチェックできないの?」「こういうの必要だと思う!!」などあれば是非是非ご意見いただければと思います。GitHubのIssueやDiscussions、Twitterの@cloud10designs宛でメンションやDM、もしくはA11yjでも、どこでも受け付けています。

では。あなたのマークアップに安寧を🖖

Discussion