RESTエンドポイントを使用したカスタムコンポーネントのリンティング
RESTエンドポイントを使用してカスタムコンポーネントをリンティングするためのAxe DevTools Linterの使い方ガイド
この記事では、Axe DevTools Linter RESTエンドポイントを使用して、カスタムコンポーネントのアクセシビリティエラーを見つける方法を紹介します。
この記事は、Axe DevTools Linter REST エンドポイントの利用者を対象としています。VS Code の Axe Accessibility Linter 拡張機能や JetBrains プラグインを使用する場合は、VS Code用のAxe Accessibility Linter拡張機能やJetBrainsのプラグインによるカスタムコンポーネントのリンティングを参照してください。
前提条件
Axe DevTools Linter の SaaS バージョンまたはオンプレミスバージョンへのアクセスが必要です。詳細は、Axe DevTools Linter SaaS APIキーの取得方法またはAxe DevTools Linterオンプレミスエディションのセットアップを参照してください。
また、以下の条件を満たすRESTツールが必要です。
- POSTリクエストを送信できる
Authorizationヘッダーを追加することができます (Axe DevTools Linter の SaaS バージョンの場合)- カスタムコンポーネントリンティングのガイド
Axe DevTools Linterを使用してソースコードをリンティングする際、HTTPリクエストにソースと設定を含むJSONボディを提供します。たとえば、次のHTMLは
Axe DevTools Linter を使用してソースコードをリントする際、HTTP リクエストにソースや設定を含む JSON ボディを提供します。例えば、次の HTML では、img 要素の使用が示されています。
<img src="path/to/image.jpg"/>Axe DevTools Linterに送信するリクエストのJSONボディは次のようになります。
このJSONをREST POSTリクエストとしてAxe DevTools Linterに送信します。
{
"source": "<img src=\"path/to/image.jpg\"/>",
"filename": "image-demo.html"
}この JSON を Axe DevTools Linter に REST POST リクエストとして /linter-source エンドポイントに送信します。詳細は参考資料ののリファレンスドキュメントをご覧ください。を参照してください。
この
この img 要素に alt 属性がないため、Axe DevTools Linter からアクセシビリティのエラーが発生します:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures <img> elements have alternate text or a role of none or presentation",
"endColumn": 31,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
"lineContent": "<img src=\"path/to/image.jpg\"/>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "image-alt"
}
]
}
}次のサンプルは、
次のサンプルは、custom-image カスタムコンポーネントの例を示しています:
<custom-image src="path/to/image.jpg"></custom-image>サーバーは、
{
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"filename": "custom-image.html"
}custom-image と img の間にマッピングがないため、Axe DevTools Linter は欠落している alt 属性を検出できないので、サーバーはアクセシビリティのエラーなしで応答します:
{
"report": {
"errors": []
}
}custom-image を img にマッピング
custom-image と img の間にマッピングを提供すると、Axe DevTools Linter はカスタムコンポーネントを標準の HTML 要素としてマッピングし、アクセシビリティのエラーを見つけることができます。マッピングは config オブジェクトの一部である global-components 設定オプションを使用して指定できます:
{
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}Axe DevTools Linterは以下の応答を返します。
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures <img> elements have alternate text or a role of none or presentation",
"endColumn": 54,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
"lineContent": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "image-alt"
}
]
}
}同じマッピングを以下のいずれかの構文で示すこともできます。
{
"config": {
"global-components": {
"custom-image": {
"element": "img"
}
}
}
}または、別の方法として、element を el として省略することもできます:
{
"config": {
"global-components": {
"custom-image": {
"el": "img"
}
}
}
}上記のようにエレメントマッピングを使用する場合、カスタムコンポーネントからのすべての属性が発行されたエレメントにコピーされ、その発行されたエレメントがリンティングされます。
アクセシビリティの問題を修正する
アクセシビリティの問題を解決するために、custom-image に alt 属性を追加することができます (以下のリクエストの JSON ボディで示されています):
{
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\" alt=\"alt text\"></custom-image>\n\n"
}カスタムコンポーネントに必要な alt 属性が含まれているため、サーバーは以下の空の errors 配列で応答します (すべての その他の custom-image コンポーネント上の属性と共に、img 要素にコピーされました):
{
"report": {
"errors": []
}
}alternative-text 属性のマッピング
カスタム画像コンポーネントが代わりに別の属性を使用して代替テキストを示す場合、その属性を設定で指定できます。例えば、custom-image コンポーネントが alt の代わりに alternative-text 属性を使用する場合、以下のように示されます:
<custom-image src="path/to/image.jpg" alternative-text="alt text"></custom-image>この場合、以下に示すように alternative-text 属性と alt 属性の間のマッピングを attributes 配列で指定できます:
{
"config": {
"global-components": {
"custom-image": {
"element": "img",
"attributes": [
{
"alternative-text": "alt"
}
]
}
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\" alternative-text=\"alt text\"></custom-image>\n\n"
}global-components 設定は、以前のカスタムコンポーネントを HTML 要素にマッピングする際の設定とは若干異なります。要素のみを使用する場合は、文字列 ("custom-image") から別の文字列 ("img") へのマッピングを使用します。attributes 配列を含めることで、element (または el) プロパティを使用して、出力される HTML 要素を指定する必要があります。
alt-text ルールがあなたの alternative-text 属性によって満たされているため、Axe DevTools Linter は以下のように応答します:
{
"report": {
"errors": []
}
}設定で attributes 配列を指定したため、サーバーが custom-image から img へのマッピングを行う際に、attributes 配列で指定された属性のみ が出力される HTML 要素にコピーされます。
attributes を attrs として省略することもできます:
{
"config": {
"global-components": {
"custom-image": {
"attrs": [
{
"alternative-text": "alt"
}
],
"element": "img"
}
}
}
}特殊な属性値: <text>、aria-*、<element>
次のように custom-button コンポーネントを使用する場合を想定します:
<custom-button aria-controls="expand-region" aria-expanded="false" aria-colindex="1" message="Show Region"></custom-button>(このカスタムボタンは、ここには含まれていない JavaScript や CSS を使用して、div を隠したり表示したりします。)
この使用法には2つの問題があります:
- この
custom-buttonコンポーネントを直接的にbutton要素にマッピングすると、ボタンに表示するテキストコンテンツがありません。しかし、コンポーネント作成者の意図はmessage属性がテキストコンテンツとして使用されることです:<button>message属性の値</button> - 出力された
button要素にはbuttonの暗黙の役割があるため、aria-colindex属性は正しくなく、削除する必要があります。
上記のコードを Axe DevTools Linter に送信すると (global-components マッピングなしで)、次のレスポンスを受け取ります:
{
"report": {
"errors": []
}
}特殊な <text> 値
最初の問題 (button 要素のテキストコンテンツが message 属性から来ている) に対処するには、特殊な <text> 値を使用して、属性を出力される要素のテキストコンテンツにマッピングすることができます。この場合、message 属性のテキストを出力される button 要素のテキストコンテンツにコピーする必要があります。
message 属性を HTML button 要素のテキストコンテンツと見なすように Axe DevTools Linter に警告するリクエストを設定するには、特殊な <text> 値を使用して次のリクエストを送信します:
{
"config": {
"global-components": {
"custom-button": {
"attributes": [
{
"message": "<text>"
}
],
"element": "button"
}
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}message 属性を <text> として定義したため、Axe DevTools Linter に対してその属性を HTML button 要素のテキストコンテンツを message 属性の値に置き換えるように指示しました。
attributes 配列を使用したため、出力された button 要素に渡される唯一の属性は message 属性のみであり、attributes 配列にない属性は渡されません。これにより、サーバーによって不正な aria-colindex が捕捉されませんでした。
aria-* を使用
すべての ARIA 属性を渡すために、以下に示すように特殊な aria-* 値を使用できます:
{
"config": {
"global-components": {
"custom-button": {
"attributes": [
{
"message": "<text>"
},
"aria-*"
],
"element": "button"
}
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}サーバーは次のように応答します:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures ARIA attributes are allowed for an element's role",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "aria-allowed-attr"
}
]
}
}このエラーは、button 要素が暗黙の role="button" を持ち、aria-colindex を使用することがボタンに対して無効であるために発生します。aria-* では、すべての ARIA 属性が出力される要素にコピーされます; これには不正な aria-colindex 属性のコピーも含まれます。
<element>
複雑なコンポーネントでは、特定のケースでデフォルトの要素とは異なる HTML 要素を出力したい場合があります。例えば、通常はボタンのように振る舞うが、他の状態ではプレースホルダー画像のように振る舞うボタンコンポーネントがあります。<element> 値により、カスタムコンポーネント上の属性を指定して、出力される要素を決定できます。
{
"config": {
"global-components": {
"my-button": {
"element": "button",
"attributes": [
{
"use": "<element>"
},
'src',
'alt'
]
}
}
},
"filename": "aria-button.html",
"source": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>"
}この場合、my-button コンポーネント上の use 属性が出力する要素を示します。出力された img 要素に alt 属性が含まれていないため、エラーが発生します:
{
"report": {
"errors": [
{
"ruleId": "image-alt",
"helpURL": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axe-linter",
"description": "Images must have alternative text",
"lineNumber": 1,
"column": 1,
"linterType": "html",
"lineContent": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>",
"endColumn": 50
}
]
}
}すべての属性を暗黙的に引き継ぐ
attributes 配列なしでの要素マッピングのみを使用していた場合、すべての属性がデフォルトで button 要素にコピーされます:
{
"config": {
"global-components": {
"custom-button": "button"
}
},
"filename": "aria-button.html",
"source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}このサーバーレスポンスによって、custom-button からのすべての属性がアクセシビリティの問題でチェックされ、2 つのエラーが見つかったことが確認できます:
{
"report": {
"errors": [
{
"column": 1,
"description": "Ensures ARIA attributes are allowed for an element's role",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "aria-allowed-attr"
},
{
"column": 1,
"description": "Ensures buttons have discernible text",
"endColumn": 124,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/button-name?application=axe-linter",
"lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "button-name"
}
]
}
}上記の例は、カスタムコンポーネントのリントを開始する際の実用的な最初のステップは、要素マッピングから開始し (これによりすべての属性が標準の HTML 要素にコピーされます)、その後設定に追加する必要のある属性を検討すること (カスタムコンポーネントの属性を異なる属性にマッピングすべきか、<text> または aria-* を使用する必要があるかどうか) を示しています。
デフォルト属性
デフォルト属性を使用すると、1 つの属性を他にマッピングするのではなく、設定ファイルで属性の値を設定できます。例えば、次のサンプル設定では custom-menu コンポーネントを role が メニュー の li 要素にマッピングしていることを示しています:
{
"config": {
"global-components": {
"custom-menu": {
"element": "li",
"attributes": [
{
"role": {
"name": null,
"default": "menu"
}
}
]
}
}
}
}role 属性に、設定ファイルで メニュー のデフォルト値が設定されているため、ユーザーがコード内で custom-menu コンポーネントを使用する際に role 属性を指定する必要はありません。これが意味するところは、カスタムコンポーネントの実装がこれらの属性を出力要素に作成し、その値を設定するので、ユーザーがコンポーネントを使用する際にそれらを設定する必要がないということです。
オプションとして、name 値が設定で null に設定されている場合、Axe DevTools Linter はリントされたコードでユーザーがcustom-menuに指定した role 属性を無視します。
default と指定された値は、文字列であるべきです。
カスタムコンポーネント違反の分析
多くのカスタムコンポーネントが設定されている場合、レスポンス内のどの違反がカスタムコンポーネントのマッピングから来たものなのか、それとも標準の HTML から来たものなのか判別するのが難しいことがあります。リクエストボディに "properties": ["customName"] を追加することで、Axe DevTools Linter はカスタムマッピングされたコンポーネントから発生した各エラーに customName プロパティを含めます。
custom-image 例に基づくと、リクエストに"properties": ["customName"]を追加します:
{
"properties": ["customName"],
"config": {
"global-components": {
"custom-image": "img"
}
},
"filename": "c-image.html",
"source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}レスポンスには、違反を引き起こしたカスタムコンポーネントを示すcustomName プロパティがエラーに含まれるようになります:
{
"report": {
"errors": [
{
"column": 1,
"customName": "custom-image",
"description": "Ensures <img> elements have alternate text or a role of none or presentation",
"endColumn": 54,
"helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
"lineContent": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
"lineNumber": 1,
"linterType": "html",
"ruleId": "image-alt"
}
]
}
}カスタムマッピングの一部ではないコンポーネントのエラーには customName プロパティが含まれません。
関連情報
- Axe DevTools Linter REST API リファレンス には、Axe DevTools Linter が提供する様々な REST エンドポイントを使用するための詳細情報が含まれています。
- Axe DevTools Linter SaaS APIキーの取得方法は、Axe DevTools Linterのサービスとしてのソフトウェア(SaaS)バージョンを使用するためのAPIキーを取得する方法を示しています。
