WCAG 達成基準 · Level A

WCAG 2.5.2: ポインターのキャンセル

WCAG 2.5.2 は、単一のポインター(マウス、タッチ、またはスタイラス)によってトリガーされる機能が、取り消しや元に戻すことができるようにすることを求めており、誤った操作による実行を防ぎます。これは、意図せずタップやクリックしてしまう可能性のある運動障害のあるユーザーを保護します。

このルールの意味

WCAG 2.5.2 Pointer Cancellation は、単一のポインターで操作されるすべての機能に適用されます。これには、マウスクリック、タッチスクリーンでのタップ、スタイラスの押下、画面上の一点をアクティブにするその他あらゆる入力デバイスが含まれます。この達成基準は、意図しない押下やタップによって引き起こされる誤作動が、実行される前に取り消せるようにすることを目的としています。

単一ポインターのインタラクションがこの達成基準に適合するためには、WCAG 仕様で定義されている次の4つの条件のうち少なくとも1つを満たす必要があります。

  • ダウンイベントなし: 機能がダウンイベント(例: mousedowntouchstartpointerdown)でトリガーされないこと。アクティベーションはアップイベント(mouseuptouchendpointerup)でのみ行われます。
  • 中止または取り消し: アクションが完了する前に中止できる、または完了後に取り消せる仕組みが用意されていること。
  • アップリバーサル: アップイベントが、ダウンイベントでトリガーされた結果を元に戻すこと。たとえば、ポインターがターゲットの外で離された場合に元の位置に戻るドラッグ操作などです。
  • 本質的な例外: ダウンイベントでトリガーされることが機能にとって本質的であること。たとえば、キーを押した瞬間に音が鳴り始めなければならないオンスクリーンのピアノキーボードなどです。ただし、この例外は非常に限定的であり、ダウンイベントのタイミングが本質的に必要な場合にのみ適用されます。

実際の HTML と JavaScript の観点では、これは開発者がイベントリスナーをどこに付与するかに注意しなければならないことを意味します。mousedowntouchstartpointerdown を使って、フォーム送信、レコード削除、ページ遷移などのアクションを即座かつ不可逆的に実行し、かつそのアクションを取り消したり元に戻したりする手段を提供しない場合、この達成基準に明確に不適合となります。ネイティブの <button><a> 要素に対する標準的なブラウザの挙動は、デフォルトでアップイベントでアクティベーションを発火させるため、適切に実装されたネイティブコントロールは一般的に追加の対応なしでこの達成基準を満たします。

JavaScript で構築されたカスタムインタラクティブコンポーネント(ドラッグ&ドロップインターフェース、ジェスチャーベースのスライダー、カルーセルコントロール、イメージマップなど)は、もっとも一般的な不適合の原因です。キャンセルやリバーサルを提供せずに、不可逆的なロジックをダウンイベントリスナーにバインドしているコンポーネントは、この達成基準に不適合となります。

なぜ重要か

Pointer Cancellation は主に運動障害のあるユーザーを保護するために設計された達成基準ですが、その恩恵は、振戦、痙縮、微細運動の制御の制限、注意力や正確さに影響する認知障害を持つユーザーなど、幅広いユーザーに及びます。

パーキンソン病のあるユーザーが、タッチスクリーンで EC サイトのチェックアウトページを操作している状況を考えてみてください。手の震えにより、意図せず「購入を確定」ボタンに指が触れてしまうかもしれません。もし購入が touchstart イベント、つまり指が画面に触れた瞬間にトリガーされると、ユーザーはキャンセルする機会もなく即座に取引が処理されてしまいます。アクティベーションが touchend イベントにバインドされていれば、ユーザーは指を離す前にボタンからスライドさせることでアクションをキャンセルできます。アップイベントとダウンイベントのどちらにバインドするかというこの単純な違いが、何百万人ものユーザーにとって、フラストレーションのたまる体験とアクセシブルな体験の分かれ目になり得ます。

世界保健機関によると、世界で約 13 億人が何らかの障害とともに生活しており、その中で運動障害は大きな割合を占めています。障害の有無にかかわらず、小さなタッチスクリーンデバイスでは誤操作が一般的な不満の原因であり、この達成基準は一般的なユーザビリティにとっても重要です。

認知障害も重要な考慮事項です。情報処理に時間がかかるユーザーは、ボタンを押した後で誤った選択をしたことに気づく場合があります。アクションが不可逆的で、ダウンイベントでトリガーされる場合、彼らには打つ手がありません。取り消し機能やアップイベントでのアクティベーションは、こうしたユーザーが意図を確認するために必要な時間を与えます。

ビジネスの観点から見ると、誤ったフォーム送信、購入、削除を減らすことは、ユーザー満足度の向上、サポート問い合わせの削減、取引放棄率の低下につながります。アクセシブルなポインターインタラクションモデルは、トルコ国内および国際的なアクセシビリティ規制における法的責任リスクの軽減にもつながります。

関連する Axe-core のルール

WCAG 2.5.2 は手動テストを必要とし、自動アクセシビリティスキャナーだけでは信頼性の高い評価はできません。この達成基準に直接対応する特定の axe-core 自動ルールは存在しません。自動検出が不十分である理由は次のとおりです。

  • ポインターキャンセルにおいて自動化が失敗する理由: axe-core のような自動ツールは HTML を解析し、特定の ARIA や構造上の問題を検出できますが、JavaScript のイベントハンドラーの意味的な意図可逆性を信頼性高く判断することはできません。ツールは、ある要素に mousedown イベントリスナーが存在することは検出できても、そのリスナーが不可逆的なアクションをトリガーするかどうか、アプリケーションの別の場所に取り消し機構が存在するかどうか、あるいはダウンイベントのタイミングが本当に機能にとって本質的かどうかを判断することはできません。この達成基準を評価するために必要な実行時の挙動、アプリケーションの状態、ユーザーの文脈の組み合わせは、静的または DOM ベースの自動解析の範囲を超えています。
  • 手動テスターが確認すべきこと: テスターはポインターデバイスを使って各インタラクティブコントロールを操作し、アクションが押下時に発火するのか、離したときに発火するのかを正確に観察する必要があります。また、ポインターを要素の外にスライドさせてから離した場合にアクションがキャンセルされるかどうか、アクティベーション後に利用可能な取り消しまたは中止の仕組みがあるかどうかも確認しなければなりません。
  • 自動化から得られる部分的なシグナル: 一部のリンティングツールやカスタム axe ルールは、onmousedownontouchstartonpointerdown 属性を持つ要素をレビュー対象としてフラグ付けする場合がありますが、これらのフラグは適合か不適合かを判断するために人間の判断を必要とします。このような自動フラグは、決定的な不適合レポートではなく、手動調査のきっかけとして扱ってください。

テスト方法

  1. 自動スキャン(初期調査): ページに対して axe DevTools や Lighthouse を実行し、インタラクティブ要素と、手動レビュー対象としてフラグ付けされたカスタムイベントバインディングを特定します。Chrome DevTools では、Elements パネルを使用してボタン、リンク、カスタムコントロールに付与されたイベントリスナーを検査し、不可逆的なアクションをトリガーする要素に mousedowntouchstartpointerdown ハンドラーがないか確認します。
  2. マウスポインターテスト — クリック&ドラッグによるキャンセル: ページ上の各ボタン、リンク、カスタムコントロールについて、その要素上でマウスボタンを押し続けたまま、要素の境界外までポインターをドラッグし、その後でボタンを離します。ボタンを押している間(離す前)にアクションが発火する場合は不適合です。ドラッグして離れた位置でボタンを離したときにアクションが発火しない場合は、アップリバーサルまたはダウンイベントなしの条件を満たしていると判断できます。
  3. タッチデバイステスト: タッチスクリーンデバイスまたはブラウザエミュレーター(Chrome DevTools のデバイスモード)で、各インタラクティブ要素をタップして押し続け、その後指を離す前にスライドさせます。指を離す前に、タッチした瞬間にアクションが発火する場合、ダウンイベントのタイミングが本質的でない限り不適合です。要素の外で指を離したときにアクションがトリガーされないことを確認してください。
  4. キーボード操作の確認: この達成基準はポインターインタラクションに特化したものですが、すべてのインタラクティブ要素がキーボードでも操作可能であることを確認してください。Tab キーで各要素にフォーカスを移動し、Enter または Space でアクティベートして、ポインターなしでも要素に到達でき、機能することを確認します。これはより広いアクセシビリティの観点を支援します。
  5. 取り消し/中止メカニズムの検証: 本質的な例外が適用される可能性のあるダウンイベントにバインドされたアクションについては、明確な取り消しまたは中止メカニズムが存在し、支援技術を利用するユーザーを含むすべてのユーザーがアクセスできることを確認します。たとえば、ドラッグ&ドロップ操作の後に、キーボードやスクリーンリーダーで到達可能な「元に戻す」ボタンがあるかどうかを確認します。
  6. スクリーンリーダーとポインターの組み合わせテスト(NVDA + Firefox、JAWS + Chrome、VoiceOver + Safari): ポインターとスクリーンリーダーのバーチャルカーソルの両方を使ってインタラクティブ要素をアクティベートします。ポインターでトリガーされるアクションがスクリーンリーダーでトリガーされるアクションと一貫しており、予期せぬ即時の不可逆的アクションが発生しないことを確認します。
  7. コードレビュー: コードベース内でイベントリスナーのバインディングを検索します。addEventListener('mousedown'addEventListener('touchstart'addEventListener('pointerdown'、およびインラインの onmousedownontouchstart 属性を探します。各箇所について、そのハンドラーが不可逆的なアクションをトリガーしているかどうか、また WCAG の4つの条件のいずれかを満たしているかどうかを評価します。

修正方法

mousedown で不可逆的なアクション — 不適切な例

<!-- FAIL: Delete fires immediately on mousedown, no cancellation possible -->
<button onmousedown='deleteRecord(recordId)'>Delete Record</button>

<script>
function deleteRecord(id) {
  // Record is deleted immediately on button press, before the user releases
  fetch('/api/records/' + id, { method: 'DELETE' });
}
</script>

mousedown で不可逆的なアクション — 適切な例

<!-- PASS: Delete fires on click (up-event), native button behavior -->
<button onclick='deleteRecord(recordId)'>Delete Record</button>

<!-- Even better: provide confirmation dialog as an additional abort mechanism -->
<button onclick='confirmDelete(recordId)'>Delete Record</button>

<script>
function confirmDelete(id) {
  // User can cancel via the dialog — satisfies the Abort or Undo condition
  if (confirm('Are you sure you want to delete this record? This cannot be undone.')) {
    fetch('/api/records/' + id, { method: 'DELETE' });
  }
}
</script>

touchstart で発火するタッチジェスチャー — 不適切な例

<!-- FAIL: Action fires immediately on touchstart, no opportunity to abort -->
<div id='buy-btn'>Buy Now</div>

<script>
document.getElementById('buy-btn').addEventListener('touchstart', function() {
  // Purchase initiated immediately when finger touches the element
  initiatePurchase();
});
</script>

touchstart で発火するタッチジェスチャー — 適切な例

<!-- PASS: Use a native button and bind to click, which fires on touchend -->
<button id='buy-btn'>Buy Now</button>

<script>
// The 'click' event on a native button fires on the up-event (touchend/mouseup)
// giving users the ability to cancel by sliding their finger away before releasing
document.getElementById('buy-btn').addEventListener('click', function() {
  initiatePurchase();
});
</script>

アップリバーサルのないカスタムドラッグ&ドロップ — 不適切な例

<!-- FAIL: Item is moved to new position on pointerdown, not on pointerup -->
<div class='draggable' onpointerdown='moveItemToTarget(this)'>
  Drag me
</div>

アップリバーサルのあるカスタムドラッグ&ドロップ — 適切な例

<!-- PASS: Item moves to target only when pointer is released over the drop zone -->
<!-- If user drags away before releasing, item returns to original position -->
<div
  class='draggable'
  draggable='true'
  ondragstart='handleDragStart(event)'
>
  Drag me
</div>
<div
  class='drop-zone'
  ondragover='event.preventDefault()'
  ondrop='handleDrop(event)'
  aria-label='Drop zone'
>
  Drop here
</div>

<script>
function handleDragStart(event) {
  // Only records intent; does not move the item yet
  event.dataTransfer.setData('text/plain', event.target.id);
}
function handleDrop(event) {
  event.preventDefault();
  // Item is moved only on drop (up-event equivalent)
  // If user releases outside drop zone, item returns to origin — up-reversal satisfied
  const id = event.dataTransfer.getData('text/plain');
  event.currentTarget.appendChild(document.getElementById(id));
}
</script>

よくある間違い

  • フォーム送信、レコード削除、ナビゲーションなどの不可逆的なアクションを、デフォルトでアップイベント時に発火しドラッグによるキャンセルを可能にする click ではなく、mousedownpointerdown イベントにバインドしてしまうこと。
  • EC やバンキングのインターフェースで、購入、確認、データ変更を touchstart でトリガーし、一瞬の指の接触を確定したユーザー意図として扱ってしまうこと。
  • ボタンがネイティブの <button> 要素を使っているからといって、そのボタンに付与されたすべての JavaScript が自動的に適合していると想定してしまうこと。不可逆的なアクションをトリガーする addEventListener による mousedown リスナーは、この達成基準に違反します。
  • ポインターのダウンイベントでモーダルダイアログ、オーバーレイ、ページ全体のナビゲーション変更を起動し、コントロールをアクティベートするつもりのなかったユーザーを混乱させ、進行を元に戻す手段を奪ってしまうこと。
  • pointerdown でサーバーに値を確定してしまうカスタムスライダーやレンジコントロールを実装し、pointerup まで待ったり、別の確認アクションを用意しなかったこと。
  • ダウンイベントアクションの唯一の取り消しメカニズムとしてブラウザのデフォルトの confirm() ダイアログに依存し、破壊的なアクションが完了する前に支援技術が確実にこのダイアログにアクセスして操作できるかどうかをテストしていないこと。
  • ダウンイベントアクションが保留中であることを示す視覚的またはプログラム的なフィードバックを一切提供せず、ユーザーが、離す前にポインターを移動することで中止できる可能性に気づけないようにしてしまうこと。
  • 本質的な例外を広く解釈しすぎること。たとえば、実際には厳密なタイミング制約がないにもかかわらず、「クイック購入」ボタンの速度のために mousedown で発火する必要があると主張し、その主張が機能上の必然性ではなく製品上の便宜に過ぎない場合などです。
  • マウスとタッチ入力の両方でテストを行わないこと。インターフェースがマウスインタラクションではアップイベントを正しく使用していても、モバイル専用のコードパスで不可逆的なアクションを touchstart にバインドしている場合があります。
  • 取り消し機能をキーボードショートカット(例: Ctrl+Z)でのみ提供し、同等のオンスクリーンコントロールを用意しないことで、ダウンイベントでアクティベーションした後にポインターのみのユーザーがキャンセル手段を持てないようにしてしまうこと。

トルコのアクセシビリティ規制との関係

トルコの大統領通達 2025/10 は、2025年6月21日付官報第 32933 号で公布され、WCAG 2.2 標準に整合した必須のウェブアクセシビリティ要件を定めています。この通達の下では、WCAG 2.5.2 Pointer Cancellation を含むレベル A の達成基準への適合が、トルコでデジタルサービスを提供する幅広い公的・民間主体に対して法的に求められます。

この通達は幅広い組織を対象としています。公的機関および政府機関は、通達の公布日から 1 年以内にレベル A の完全な適合を達成しなければなりません。規制の対象となる民間セクターの事業者 — EC プラットフォーム、銀行・金融機関、病院・医療提供者、20万件以上の加入者を持つ通信会社、旅行代理店、民間輸送会社、国民教育省(MoNE)に認可された私立学校など — には、2 年間の適合猶予期間が与えられています。

これらの対象組織にとって、Pointer Cancellation を正しく実装しないことは、実際の規制リスクを伴います。たとえば、トルコの EC プラットフォームのモバイルチェックアウトページが touchstart で支払い確認をトリガーする場合、そのような実装は WCAG 2.5.2 に直接違反し、ひいては大統領通達にも違反することになります。振戦や運動障害、単なるタップミスによってそのプラットフォームで誤って購入を開始してしまったユーザーは、プラットフォームがアクセシビリティ義務を果たしていないと主張する法的根拠を持つことになります。

規制遵守を超えて、トルコの組織は Pointer Cancellation が単なる技術的なチェックボックスではなく、ユーザーがデジタルサービスと安全かつ意図的にやり取りできるようにするための基本的なデザイン原則であることを認識すべきです。ショッピングカートや予約システムからドキュメント管理ツールに至るまで、インタラクティブコンポーネント全体でアップイベントによるアクティベーションと取り消しメカニズムを実装することは、障害のあるユーザーだけでなくすべてのユーザーに利益をもたらすインクルーシブデザインへのコミットメントを示すものです。

通達の対象となる組織は、特にモバイル最適化されたページやカスタムインタラクティブコンポーネントにおける JavaScript のイベント処理パターンについて、体系的な監査を実施し、キャンセルやリバーサルメカニズムのないダウンイベントアクティベーションを特定して是正すべきです。これらの是正措置を文書化することは、通達の執行規定の下で求められる可能性のある適合報告義務を支援することにもなります。