フォーム コントロール、リンク、ボタンなどのインタラクティブな要素は、デフォルトでフォーカス可能でタブ移動可能です。タブ移動可能な要素は、ドキュメントの順次フォーカス ナビゲーション順序の一部です。他の要素はインタラクティブではないため、不活性です。HTML 属性を使用すると、インタラクティブな要素を非アクティブにしたり、非アクティブな要素をインタラクティブにしたりできます。
デフォルトでは、ナビゲーション フォーカスの順序は、ソースコードの順序である視覚的な順序と同じです。この順序を変更できる HTML 属性と、コンテンツの視覚的な順序を変更できる CSS プロパティがあります。HTML でタブ移動の順序を変更したり、CSS で視覚的なレンダリングの順序を変更したりすると、ユーザー エクスペリエンスに悪影響を及ぼす可能性があります。
CSS と HTML を使用して、認識されるタブ順序と実際のタブ順序を変更しないでください。次の 2 つの例に示すように、視覚的に期待される順序と異なるタブの順序は、ユーザーを混乱させ、ユーザー エクスペリエンスを損ないます。
この例では、tabindex
属性の値によってタブオーダーが混乱しています。
この例では、CSS によってコンテンツのタブ移動の順序と視覚的な順序の間にずれが生じています。
flex-flow: row-reverse;
宣言により、視覚的な順序が逆になっています。また、CSS の order プロパティが 6 番目の単語「This」に適用され、その単語が視覚的に移動しました。タブ移動の順序はコードの順序であり、視覚的な順序と一致しなくなったため、キーボード ユーザーにとってのつながりが失われています。
非アクティブな要素をインタラクティブにする
contenteditable
属性と tabindex
属性はグローバル属性であるため、任意の要素に追加して、その要素にフォーカスできるようにすることができます。フォーカス可能な要素は、autofocus
属性を設定するか、element.focus()
などのスクリプトを使用して、マウスやポインタでフォーカスすることもできます。
tabindex
属性
属性で導入されたグローバル tabindex
属性を使用すると、通常はフォーカスを受け取れない要素がフォーカスを受け取れるようになります。通常は Tab キーでフォーカスを移動できるため、この名前が付けられています。
tabindex
属性は、値として整数を受け取ります。負の値を指定すると、要素はフォーカス可能になりますが、タブ移動はできません。tabindex
の値が 0
の場合、要素はフォーカス可能でタブ移動可能になり、適用された要素がソースコード順に連続フォーカス ナビゲーション順に追加されます。1 以上の値にすると、要素がフォーカス可能でタブ移動可能になりますが、優先度の高いタブ移動シーケンスに追加されるため、避けるべきです。
このページでは、共有ボタン <share-action>
はカスタム要素です。tabindex="0"
は、通常はフォーカスできない要素をキーボードのデフォルトのタブ順に追加します。
<share-action authors="@front-end.social/@estellevw" data-action="click" data-category="web.dev" data-icon="share" data-label="share, mastodon" role="button" tabindex="0">
<svg aria-label="share" role="img" xmlns="http://www.w3.org/2000/svg">
<use href="#shareIcon" />
</svg>
<span>Share</span>
</share-action>
このページには別のカスタム要素があります。ローカル ナビゲーションには、tabindex
値が負のカスタム要素があります。
<web-navigation-drawer type="standard" tabindex="-1">
負の値を持つ tabindex
属性は、要素をフォーカス可能にしますが、タブ移動可能にはしません。要素は HTMLElement.focus()
の使用などによりフォーカスを受け取ることができますが、順次フォーカス ナビゲーションの順序には含まれません。タブ移動できないフォーカス可能な要素の慣例は、tabindex="-1"
を使用することです。インタラクティブ要素に tabindex="-1"
を追加すると、その要素はタブ移動できなくなります。
element.focus()
メソッドを使用すると、フォーカス可能な要素にフォーカスを設定できます。ブラウザは、フォーカスされた要素をスクロールして表示します。このため、非表示の要素にフォーカスすることはユーザー エクスペリエンスの低下につながるため、element.focus({preventScroll:true})
の使用は避けてください。
ドキュメントをクエリして、どの要素にフォーカスがあるかを確認するには、読み取り専用の Document.activeElement
プロパティを使用します。
tabindex
が 1
以上の要素は、別のタブ順序に含まれます。Codepen で確認できるように、タブ移動は、まず低い値から高い値の順で別のシーケンスで始まり、次にソース順で通常のシーケンス(tabindex
が設定されていないか、tabindex="0"
)の要素を移動します。
tabindex
に正の値を指定すると、要素が優先順位付きのフォーカス シーケンスに配置され、フォーカス順序が混乱する可能性があります。tabindex
を使用して DOM の順序を変更することは避けてください。タブ順序の変更は、ユーザー エクスペリエンスの低下につながるだけでなく、デベロッパーによる管理やメンテナンスも難しくなります。
contenteditable
属性
contenteditable
属性については、すでに説明しました。要素に contenteditable="true"
を設定すると、その要素は編集可能になり、フォーカス可能になり、タブ順序の一部になります。フォーカス動作は tabindex="0"
の設定と似ていますが、同じではありません。ネストされた contenteditable
要素はフォーカス可能ですが、タブ移動はできません。ネストされた contenteditable
要素をタブ移動可能にするには、tabindex="0"
を追加します。これにより、要素が順次フォーカス ナビゲーションの順序に追加されます。
インタラクティブな要素に autofocus
を付与する
ブール値 autofocus
は任意の要素に設定できるグローバル属性ですが、これによって非アクティブな要素がインタラクティブになることはありません。ページが読み込まれると、autofocus
属性を持つ最初のフォーカス可能な要素がフォーカスを受け取ります。ただし、その要素が表示されていて、<dialog>
にネストされていない場合に限ります。
コンテンツに自動的にフォーカスを設定すると、混乱を招く可能性があります。フォーム コントロールで autofocus
を設定すると、ページ読み込み時にフォーム コントロールがスクロールして表示されます。スクリーン リーダーのユーザーやビューポートの小さいユーザーを含むすべてのユーザーが、フォームの指示を「見ることができない」可能性があります。フォーム コントロールの通常表示されるラベルをスクロールして通り過ぎてしまう可能性もあります。autofocus
属性は、ドキュメントの順次フォーカス ナビゲーションの順序を変更しません。自動フォーカス要素の前に配置されているシーケンス内の要素はスキップされます。これらの理由から、autofocus
属性を含めることはおすすめしません。
「autofocus
を使用しない」という推奨事項の例外は、<dialog>
要素内に autofocus
属性を含めることです。ダイアログが開くと、ブラウザは <dialog>
内の最初のフォーカス可能なインタラクティブ要素に自動的にフォーカスします。つまり、要素に autofocus
を追加する必要はありません。ダイアログが開いたときに、ダイアログ内の特定のインタラクティブ要素にフォーカスが確実に移動するようにするには、その要素に autofocus
属性を追加します。
<dialog open>
<form method="dialog">
<button type="submit" autofocus>close</button>
</form>
</dialog>
閉じる <button>
に設定された autofocus
属性により、ダイアログが開いたときにフォーカスを受け取ることができます。ダイアログの最初の要素であるため、いずれにしてもフォーカスが設定されます。デフォルトでは、ダイアログが開くと、ダイアログ内の別の要素に autofocus
属性が設定されていない限り、ダイアログ内の最初のフォーカス可能な要素がフォーカスを受け取ります。
インタラクティブな要素を非アクティブにする
タブ順序からインタラクティブ要素を削除できる HTML 属性もあります。フォーカス可能な要素に負の tabindex
を含める、サポートされているフォーム コントロールに disabled
属性を追加する、コンテナにグローバル inert
属性を追加すると、要素がタブ移動できなくなります。これら 3 つの属性は相互に置き換えることはできません。
負の tabindex
値
負の値を持つ tabindex
属性は、要素をフォーカス可能にしますが、タブ移動可能にはしません。リンク、ボタン、フォーム コントロール、contenteditable
要素など、デフォルトでフォーカス可能な要素に tabindex="0"
を追加する必要はありません。負の値の tabindex
を追加すると、通常はタブ移動可能な要素が順次フォーカス ナビゲーションの順序から削除されます。
tabindex
の値が負の場合、キーボード ユーザーは操作可能な要素にフォーカスできなくなりますが、要素は無効になりません。ポインタ ユーザーは引き続き要素にフォーカスできます。要素を無効にするには、disabled
属性を使用します。
無効
ブール値の disabled 属性は、適用されたフォーム コントロールとその子孫(存在する場合)をフォーカス不可にします。無効化されたフォーム コントロールは、フォーカスできず、クリック イベントを取得せず、フォーム送信時に送信されません。
disabled
はグローバル属性ではありません。これは、<button>
、<input>
、<optgroup>
、<option>
、<select>
、<textarea>
、フォーム関連のカスタム要素、<fieldset>
に適用されます。<optgroup>
または <fieldset>
に設定すると、<fieldset>
の最初の <legend>
の内容を除き、すべての子フォーム コントロールが無効になります。
disabled
をサポートする要素は、:disabled
疑似クラスと :enabled
疑似クラスでもターゲットにできます。disabled
属性で無効になっている要素は、accent-color
が設定されている場合でも、通常はユーザー エージェントのスタイルシートで薄いグレーでスタイル設定されます。
ブール値属性であるため、この属性が存在すると、通常は有効になっている要素が無効になります。false
に設定することはできません。無効にした要素を再度有効にするには、通常 Element.removeAttribute('disabled')
を使用して、属性を削除する必要があります。
HTMLInputElement.disabled
プロパティを使用すると、入力が無効になっているかどうかを確認できます。disabled
はグローバル属性ではないため、HTMLElement から継承されませんが、HTMLSelectElement
や HTMLTextareaElement
などのサポート対象の要素インターフェースには、同じ読み取り専用プロパティがあります。
disabled
属性は、tabindex
または contenteditable
でフォーカス可能にされた通常の inert
要素には適用されません。また、<form>
要素にも適用されません。これらの要素を無効にするには、グローバル inert
属性を使用します。
inert
属性
inert
グローバル ブール値属性が要素に追加されると、その要素とすべてのネストされたコンテンツが無効になります。つまり、クリックしたり、タブで移動したりできなくなります。また、ユーザー補助ツリーからも削除されます。inert
は任意の要素に適用できますが、一般的には、画面外のコンテンツや非表示のコンテンツなど、コンテンツのセクションに使用されます。
disabled
をフォーム コントロールに適用すると、ブラウザはデフォルトのスタイルを提供し、:disabled
疑似クラスを使用してスタイルを設定できます。inert
属性は視覚的なインジケーターを提供せず、一致する疑似クラスもありません([inert]
属性セレクタは一致します)。
スタイルで非アクティブであることを示さずに、表示されているコンテンツに inert
を使用すると、ユーザー エクスペリエンスが低下する可能性があります。非アクティブなコンテンツはスクリーン リーダーのユーザーが利用できないため、スクリーン リーダーのユーザーが画面上でアクセシビリティ ツールで利用できないコンテンツを目にすると、混乱を招く可能性があります。CSS で非アクティブであることを明確にします。
フォーカスが非表示のコンテンツに移動しないようにしてください。フォーカス時に自動的にビューに表示されないオフスクリーンでレンダリングされたものは、inert にする必要があります。コンテンツが非表示になっていても、フォーカスが当たると表示される場合(コンテンツへのスキップ リンクなど)は、非アクティブにする必要はありません。
理解度を確認する
フォーカスに関する知識をテストします。
フォーカスできない要素は、どのように説明されますか?
要素に disabled
属性がある場合、何が true になりますか?