アクセス不可能なアクション

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

インタラクティブ要素がVoiceOverで操作可能であることを確認する

Not for use with personal data
note

これは実験的なルールであり、その結果はベータテスト中と見なされます。詳細はこちらをご覧ください: 実験的なルール とその改善にどのように貢献できるか。

WCAG 2.0 - 2.1.1 A Impact - Critical

チェック内容

インタラクティブ要素は、支援技術によって操作できるべきです。このルールは、インタラクティブ要素に関連付けられたアクションがフォーカス可能であり かつ VoiceOverを使用してトリガーできることを確認します。

概要

  • このルールはユーザーに重大な影響を与えます
  • このルールは、VoiceOverがフォーカスできないか、アクティブにできないインタラクティブ要素を指摘します
  • これは、要素自体がフォーカス可能でない場合や、フォーカス可能な親要素内にない場合に発生します
  • フォーカス可能な親要素内にあるインタラクティブ要素は、アクションやジェスチャーレコグナイザー、またはアクティベーションポイントが検出されない場合、アクセス不可能です

ユーザーへの影響

支援技術ユーザーが最も影響を受けます。VoiceOverがインタラクティブ要素にフォーカスできるが、アクティブにできない場合、ユーザーはフォームの送信、設定の切り替え、または別の画面へのナビゲートなどの重要なアクションを完了できない可能性があります。これは、アプリとのやり取りにVoiceOverのみに依存する人々に対して完全な障壁を作ります。

アクセス不可能なアクションの問題を確認する

  1. VoiceOverをオンにする
  2. 要素にフォーカスする
  3. 次のうちいずれかが起こります:
    • アクセス不可能:ユーザーはVoiceOverを使って要素をアクティブにすることができません
    • アクセス可能:ユーザーはVoiceOverを使って要素をアクティブにすることができます

問題の修正

アクセス不可能なアクションの問題が発生するシナリオは様々です。修正は要素の構造に依存します。以下のアプローチを確認し、レイアウトに対応するものを使用してください。

UIKit

要素の構造に応じて、いくつかのアプローチがあります。

Storyboardでの修正 — アクティブなコントロールがアクセシビリティ要素であることを確認してください:

  1. 問題のある要素を選択します。 InaccessibleAction Inspectorsパネルが表示されていることを確認します。
  2. Identity Inspectorを選択します。
  3. アクセシビリティの下で、アクティブなコントロールの「有効」チェックボックスが選択されていることを確認してください。 別の選択肢として、要素のアクセシビリティパスを変更することができます:アクティブなコントロール、そのラベル、および含む要素のための手順1–3を繰り返します。
  4. アクティブなコントロールのみに「有効」チェックボックスが選択されていることを確認し、ラベルや含む要素には選択しないでください。 コード上で、アクセシビリティパスにラベルとアクティブコントロールの両方を含めるよう更新します(下記のコード上でのアクセシビリティパスの修正を参照)。別の解決策は、VoiceOverのデフォルトのアクティベーションポイントが到達できるように、アクティブなコントロールを親の中で中心に配置することです:

問題のある要素を選択します。

  1. Inspectorsパネルが表示されていることを確認します。
  2. アクティブなコントロールを選択します。
  3. Size Inspectorを選択します。

アクティブなコントロールが含む要素内で水平および垂直に中心に配置されていることを確認します。

  1. コードで修正: InaccessibleAction issue.
  2. Ensure that the Inspectors Panel is visible.
  3. Select the active control.
  4. Select the Size Inspector.
  5. Ensure that the active control is centered horizontally and vertically within its containing element.

Fix in code:

アクティブコントロールの isAccessibilityElement を次のように設定します: true以下を行います:

buttonContainerView.isAccessibilityElement = true

含まれるビューにタップジェスチャーレコグナイザーを追加します:

buttonContainerView.addGestureRecognizer(UITapGestureRecognizer(target: self, selector: #selector(buttonTapped)))

ボイスオーバーがアクティブコントロールの accessibilityActivationPoint をトリガーするように、親ビュー内で中心に配置します:

buttonContainerView.button.centerXAnchor.constraint(equalTo: buttonContainerView.centerXAnchor).isActive = true
buttonContainerView.button.centerYAnchor.constraint(equalTo: buttonContainerView.centerYAnchor).isActive = true

アクセシビリティパスを更新して、ラベルとアクティブコントロールの両方を含めます。

ラベルと親要素の isAccessibilityElement=false を設定し、コントロール自体(この場合は toggleだけがアクセシビリティ要素となるようにします。

// 1. Only the toggle should be an accessibility element
toggleContainerView.toggle.isAccessibilityElement = true
toggleContainerView.label.isAccessibilityElement = false
toggleContainerView.isAccessibilityElement = false

// 2. Expand the toggle's accessibilityPath to encompass the full container
// so VoiceOver's focus ring covers both the label and the toggle
let containerFrame = toggleContainerView.superview!.convert(toggleContainerView.frame, to: toggleContainerView.superview)
toggleContainerView.toggle.accessibilityPath = UIBezierPath(rect: containerFrame)

SwiftUI

この問題は、ほとんどの標準的なSwiftUIの要素やコントロールでは発生しませんが、カスタムコントロールや要素が誤ってグループ化された場合に発生する可能性があります。

ステッパー、スライダー、トグルの動作を模倣するカスタムコントロールを作成する場合、 .accessibilityRepresentation を使用して、カスタムコントロールに標準と同じアクセシビリティ動作を与えます:

// Add .accessibilityRepresentation on a custom Toggle view
HStack {
    Text("Dark mode is \(getDarkModeStatus().localized)")
    Image(systemName: getDarkModeImage())
}.onTapGesture {
    isOn.toggle()
}
.accessibilityRepresentation {
    Toggle(isOn: $isOn, label: {
        Text("Dark mode is \(getDarkModeStatus().localized)")
    })
}

ビューをまとめる際には、 .accessibilityElement(children: .combine) または .accessibilityElement(children: .contain) を使用して、子コントロールのすべてのアクションがアクセス可能であり続けるようにします:

VStack(alignment: .leading) {
    Text("Adjust settings below")
        .accessibilityElement(children: .ignore)
    Divider()
    Toggle(isOn: $isOn) {
        Text("Dark Mode is \(toggleStateText())")
    }
    .accessibility(value: Text("Dark Mode is \(toggleStateText())"))
}
.accessibilityElement(children: .combine)
.accessibilityLabel(Text("Adjust settings below"))

含まれるビューにステッパーやスライダーのような調整可能なコントロールがある場合、 .accessibilityAdjustableAction を使用して最良のアクセシビリティ体験を提供します:

VStack {
    Text("Adjust the stepper below to update dog petting data".localized)
    Divider()
    HStack {
        Stepper(value: $value) {
            Text("Total dogs pet today \($value.wrappedValue)")
        }.accessibilityElement(children: .ignore)
    }
}
.accessibilityElement(children: .combine)
.accessibilityValue(Text("\($value.wrappedValue)"))
.accessibilityAdjustableAction({ direction in
    switch direction {
    case .increment:
        value += 1
    case .decrement:
        value -= 1
    @unknown default:
        print("unknown direction used")
    }
})

React Native

この問題は、React Nativeの標準的なタッチ可能または押下可能コントロールでは稀ですが、カスタムコントロールで発生する可能性があります。

オプション1: 親ビューにフォーカスを処理させる

含まれるビューの accessible 属性を true に設定し、 accessibilityElementsHiddenfalseに設定し、適切な accessibilityRoleを割り当てます:

<View
  accessible={true}
  accessibilityElementsHidden={false}
  accessibilityRole='link'
  accessibilityLabel='Learn more about Deque'
  onTouchStart={openLink}
>
  <Image 
    source={DequeLogo}
    style={{ width: 100, height: 100 }} 
  />
</View>

オプション2: 要素自体にフォーカスを処理させる

を設定し、 accessibleaccessibilityElementsHidden、そして accessibilityRole をコントロールに直接設定します:

<Image
  source={DequeLogo}
  accessible={true}
  accessibilityElementsHidden={false}
  accessibilityRole='link'
  accessibilityLabel='Learn more about Deque'
  onTouchStart={openLink}
  style={{ width: 100, height: 100 }}
/>

Flutter

FlutterのMaterialウィジェット(ElevatedButtonIconButton、など)は、スクリーンリーダーにタップアクションを自動的に公開します。 GestureDetector、それらを MergeSemantics でラップし、 Semantics ウィジェットを使用して、スクリーンリーダーが要素を1回のフォーカスで検出およびアクティブ化できるようにします。

MergeSemantics(
  child: Semantics(
    button: true,
    label: 'Archive item',
    child: GestureDetector(
      onTap: () {},
      child: Container(
        padding: const EdgeInsets.all(12.0),
        color: Colors.green.shade100,
        child: const Text('Archive item'),
      ),
    ),
  ),
)

このルールを無視してもいいですか?

アクセシブルでないアクションは、 クリティカルインパクト をユーザーに与えるため、これらの問題の修正を強くお勧めします。これは実験的なルールであるため、結果を手動で確認する必要があります。要素がボイスオーバーによってアクティブ化可能であると確認した場合、その検出を無視することが許容されるかもしれません。 ルールを無視することについて詳しく学ぶ

リソース

Deque University コースページ

注:Deque Universityのリソースへの完全なアクセスには、サブスクリプションが必要です。

その他のリソース