ARIA: radio ロール
radio
ロールは radiogroup
内のチェック可能なラジオボタンのグループの 1 つで、一度に複数のラジオボタンをチェックすることはできません。
解説
ラジオボタンはチェック可能な入力で、他のラジオボタンと関連付けられ、一度にチェックできるのは 1 つだけです。ラジオボタンは radiogroup
にまとめられなければならず、これでどのラジオボタンが同じ値に影響するかを示します。
<div role="radiogroup" aria-labelledby="legend25" id="radiogroup25">
<p id="legend25">Ipsum and lorem?</p>
<div>
<span
role="radio"
aria-checked="false"
tabindex="0"
aria-labelledby="q25_radio1-label"
data-value="True"></span>
<label id="q25_radio1-label">True</label>
</div>
<div>
<span
role="radio"
aria-checked="false"
tabindex="0"
aria-labelledby="q25_radio2-label"
data-value="False"></span>
<label id="q25_radio2-label">False</label>
</div>
<div>
<span
role="radio"
aria-checked="true"
tabindex="0"
aria-labelledby="q25_radio3-label"
data-value="huh?"></span>
<label id="q25_radio3-label">What is the question?</label>
</div>
</div>
role
属性は意味づけを追加するだけです。 HTML radio にネイティブに備わっている機能はすべて JavaScript と HTML の tabindex
属性で追加する必要があります。
メモ:
ARIA の最初のルールは、ネイティブの HTML 要素や属性が要求される意味づけや動作を持っている場合、要素を再利用して ARIA を追加する代わりにそれを使用することです。代わりに、ネイティブの HTML <input type="radio">
(<label>
が関連付けられたもの)を使用してください。
<fieldset>
<legend>Ipsum and lorem?</legend>
<div>
<input type="radio" value="True" id="q25_radio1" name="q25" />
<label for="q25_radio1">True</label>
</div>
<div>
<input type="radio" value="False" id="q25_radio2" name="q25" />
<label for="q25_radio2">False</label>
</div>
<div>
<input type="radio" value="huh?" id="q25_radio3" name="q25" checked />
<label for="q25_radio3">What is the question?</label>
</div>
</fieldset>
ネイティブ HTML のラジオフォームコントロール (<input type="radio">
) は 2 つの状態("checked" と "not checked")を持ちます。同様に、 role="radio"
の要素は、 aria-checked
属性で 2 つの状態を公開することができます。 true
はチェックされた状態を表し、 false
はチェックされていない状態を表します。 aria-checked
の値である mixed
は、ラジオボタンには使用しません。
ラジオボタンがチェックされる場合、 radio 要素は aria-checked
を設定するには true
を保有します。チェックされていない場合、 aria-checked
は false
に設定されます。
各ラジオボタン要素は radio
というロールを保有します。 radio ロールは常に radiogroup
内で他にも関連する radio と一緒に入っている必要があります。ラジオボタンをラジオグループ内に入れることができない場合、グループ化されていないラジオボタンの id
をスペース区切りのリスト値として radiogroup
要素の aria-owns
属性の値として使用し、 radiogroup
とそのラジオメンバーとの関係を示します。
各 radio 要素はそのコンテンツによってラベル付けされるか、 aria-labelledby
によって参照される可視ラベルを持つか、または aria-label
で指定するラベルを持ちます。格納する radiogroup
要素は aria-labelledby
で参照する可視ラベルを持つか、aria-label
で指定するラベルを持つ必要があります。ラジオグループまたは各ラジオボタンに関する追加の情報を提供する要素が存在する場合、それらの要素は aria-describedby
プロパティを持つ radiogroup
要素または radio 要素によって参照されなければなりません。
radio
は操作可能なコントロールなので、フォーカス可能でキーボードアクセス可能でなければなりません。もしこのロールがフォーカス可能でない要素に適用されている場合は、 tabindex
属性を使用して変更してください。ラジオを有効にするキーボードショートカットは Space キーです。 JavaScript を使用して、ラジオがチェックされたときに aria-checked
属性を true
に切り替え、同時にグループ内の他のすべてのラジオの役割が aria-checked="false"
に設定されるようにしてください。
プログラムでラジオボタンがラジオグループから選ばれなければならないことを示すには、 radiogroup
要素に true
の値を持つ aria-required
属性を指定しなければなりません。個々の ARIA ラジオボタンに aria-required
属性を使用することは想定されていません。
子孫はすべて表示用
プラットフォームのアクセシビリティ API で表すと、テキストしか格納できないユーザーインターフェイスコンポーネントの型があります。アクセシビリティ API は radio
に格納された意味づけ要素を表す方法を持っていません。この制限に対応するために、ブラウザーは radio
要素の子孫要素すべてに自動的にロール presentation
を適用します。
例えば、見出しを含む次の radio
要素を考えてみましょう。
<div role="radio"><h6>name of my radio</h6></div>
radio
の子孫は存在するので、以下のコードは等価です。
<div role="radio"><h6 role="presentation">name of my radio</h6></div>
支援技術ユーザーの視点から見ると、上記コードスニペットはアクセシビリティツリーでは以下と等価なので、見出しは存在しません。
<div role="radio">name of my radio</div>
関連する WAI-ARIA ロール、状態、プロパティ
radiogroup
ロール-
ラジオボタンは
radiogroup
というロールを持つ要素に格納されているか、自分自身で所有しています。マークアップ内でradiogroup
内に入れ子にすることができない場合、radiogroup
のaria-owns
属性はグループ内の入れ子になっていないラジオボタンのid
値を格納します。 aria-checked
-
aria-checked
の値は radio の状態を定義します。 radio 要素で使用する場合、この属性は 2 つの取りうる値のうちの一つを保有します。
メモ: role="radio"
をキーボードフォーカスを受け付けない要素に使用する場合は、 tabindex
属性を使用してください。例えば、 <div>
や <span>
などです。
キーボード操作
- Tab + Shift
-
ラジオグループへのフォーカスの移動と、ラジオグループからのフォーカスの移動。ラジオグループにフォーカスが移動し、ラジオボタンがすでにチェックされている場合、チェックされたボタンにフォーカスが設定されます。どのラジオボタンもチェックされていない場合は、グループの最初のラジオボタンに設定します。
- Space
-
まだチェックされていないラジオボタンをチェックします。ラジオグループの前回チェックしたラジオボタンのチェックを外します。
- → および ↓
-
グループ内の次のラジオボタンにフォーカスを移動し、チェックされます。前回フォーカスが当たったラジオボタンのチェックは外されます。最後のラジオボタンにフォーカスがある場合、フォーカスは最初のラジオボタンに移動します。
- ← および ↑
-
グループ内の前回チェックされたラジオボタンにフォーカスを移動し、前回フォーカスされたラジオボタンのチェックを外します。最初のラジオボタンにフォーカスがある場合、フォーカスは最後のラジオボタンに移動します。
ツールバー内のラジオボタン
矢印キーはツールバーの要素間を移動するために使用し、 Tab キーはツールバーにフォーカスを移したり戻したりするので、ラジオグループがツールバーの中に入れ子になっている場合、ラジオグループのキーボード操作はツールバーの中にないラジオグループとは少し異なります。詳細は radiogroup
のキーボード操作を参照してください。
必要な JavaScript
onClick
-
aria-checked
属性の値を変更することによって、ラジオボタンの状態を変更するラジオボタンと関連付けられたラベルの両方をマウスでクリックする処理と、ラジオボタンの外観を変更して、目の見えるユーザーにはチェックされているかチェックされていないかに見えるようにします。 onKeyPress
-
ユーザーが Space キーを押してラジオボタンの状態を変更する場合、
aria-checked
属性の値とラジオボタンの外観を変更して、目の見えるユーザーにはチェックされているかチェックされていないかに見えるように処理します。
例
次の例では、 ARIA を使用して、それ以外の一般的な要素をラジオボタンとして公開されるように変更しています。 CSS と JavaScript を使用して、要素のチェック状態またはチェックされていない状態を視覚的およびプログラム的に変更しています。
HTML
<div role="radiogroup" aria-labelledby="legend" id="radiogroup">
<p id="legend">
Should you be using the <code>radio</code> role or
<code><input type="radio"></code>?
</p>
<div>
<span
role="radio"
aria-checked="true"
tabindex="0"
aria-labelledby="ariaLabel"
data-value="True"></span>
<label id="ariaLabel">ARIA role</label>
</div>
<div>
<span
role="radio"
aria-checked="false"
tabindex="0"
aria-labelledby="htmllabel"
data-value="False"></span>
<label id="htmllabel">HTML <code><input type="radio"></code></label>
</div>
</div>
CSS
[role="radio"] {
padding: 5px;
}
[role="radio"][aria-checked="true"]::before {
content: "(x)";
font-family: monospace;
}
[role="radio"][aria-checked="false"]::before {
content: "( )";
font-family: monospace;
}
JavaScript
意味づけされていない HTML からラジオボタンを作るには、多くの JavaScript が必要になります。
// initialize all the radio role elements
const radioGroups = document.querySelectorAll('[role="radiogroup"]');
for (let i = 0, groups = radioGroups.length; i < groups; i++) {
const radios = radioGroups[i].querySelectorAll("[role=radio]");
for (let j = 0, radiobuttons = radios.length; j < radios; j++) {
radios[j].addEventListener("keydown", function () {
handleKeydown();
});
radios[j].addEventListener("click", function () {
handleClick();
});
}
}
// handle mouse and touch events
let handleClick = function (event) {
setChecked(this);
event.stopPropagation();
event.preventDefault();
};
// handle key presses
let handleKeydown = function (event) {
switch (event.keyCode) {
case 32: // space
case 12: // return
currentChecked();
break;
case 38: // up
case 37: // left
previousRadioChecked();
break;
case 40: // down
case 39: // right
nextItemChecked();
break;
default:
break;
}
event.stopPropagation();
event.preventDefault();
};
// when a radio is selected, give it focus, set checked to true;
// ensure all other radios in radio group are not checked
setChecked = function () {
// uncheck all the radios in group
// iterated through all the radios in radio group
// eachRadio.tabIndex = -1;
// eachRadio.setAttribute('aria-checked', 'false');
// set the selected radio to checked
// thisRadio.setAttribute('aria-checked', 'true');
// thisRadio.tabIndex = 0;
// thisRadio.focus();
// set the value of the radioGroup to the value of the currently selected radio
};
ラジオボタンのグループ内の各ラジオボタンの名前が同じである意味づけされた HTML 要素を使用していれば、 JavaScript(あるいは CSS)は必要ありませんでした。
<fieldset>
<legend>
Should you be using the <code>radio</code> role or
<code><input type="radio"></code>?
</legend>
<div>
<input type="radio" name="bestPractices" id="ariaLabel" value="True" />
<label for="ariaLabel">ARIA role</label>
</div>
<div>
<input type="radio" name="bestPractices" id="htmllabel" value="False" />
<label for="htmllabel">HTML <code><input type="radio"></code></label>
</div>
</fieldset>
ベストプラクティス
ARIA の最初のルールは、ネイティブの HTML 要素や属性に要求される意味づけや動作がある場合、要素を再利用して ARIA ロール、状態、プロパティを追加してアクセシビリティを持たせるのではなく、それを使用することです。このように、 JavaScript と ARIA でラジオの機能を再作成する代わりに、ネイティブの HTML ラジオボタンフォームコントロールを使用することを推奨します。