WCAG 達成基準 · Level AA

WCAG 2.5.7: ドラッグ操作

WCAG 2.5.7 は、ドラッグ動作を使用するあらゆる機能について、ドラッグが本質的に不可欠でない限り、ドラッグを伴わない単一ポインター操作でも実行できるようにすることを求めています。これにより、ドラッグジェスチャーを確実に行うことができない運動障害のあるユーザーも、すべての機能に引き続きアクセスできるようになります。

このルールの意味

WCAG 2.5.7 — Dragging Movements(ドラッグ操作、レベルAA、WCAG 2.2で追加)は、操作にドラッグ動作を用いるすべての機能について、ドラッグを伴わない単一ポインタ操作によっても実行できなければならないと定めています。ただし、その機能にとってドラッグ動作が本質的であり、代替メカニズムが存在しない場合は除きます。

ドラッグ動作とは、ポインタを押し下げたまま保持し、新しい位置まで移動させてから離すというインタラクションとして定義されます。一般的な例としては、ドラッグ&ドロップによるリスト項目の並べ替え、スプリッターハンドルをドラッグして行うパネルのサイズ変更、スライダーのつまみをつかんで引く操作、キャンバス上への描画、かんばんカードの並べ替えなどがあります。これらすべてのパターンには、同等の単一ポインタ代替手段 — つまり、ポインタボタンを押したまま移動させる必要のないメカニズム — を用意しなければなりません。

単一ポインタという制約は重要です。代替手段はキーボードショートカットである必要はなく、マウスクリックやタップなど、接触点が1つだけで、押している間に継続的な移動を必要としない操作であれば構いません。たとえば、ユーザーがトラック上の任意の位置をクリックしてその値にジャンプできるスライダーは、トラックをクリックする操作がドラッグを伴わない単一ポインタ操作であるため、この達成基準を満たします。

合格とみなされる例: ドラッグ可能なリストに、上下矢印ボタンや位置指定ダイアログも用意している場合;トラック上のどこでもクリックを受け付けるレンジスライダー;数値入力やダブルクリックで折りたたみできる機能も備えたリサイズ可能なパネル;ドラッグによるパンに加えてナビゲーション矢印のクリックでもパンできる地図。

不合格とみなされる例: 項目の並べ替え方法がドラッグしかないソート可能リスト;代替手段のないスプリットペインのリサイズバー;ボタンによる代替がなく、ドラッグ&ドロップでしかファイルをアップロードできないUI;色相を選ぶ方法が、数値やテキスト入力の代替なしにグラデーションストリップ上をドラッグすることだけになっているカラーピッカー。

公式な例外: この達成基準は、ドラッグが本質的な場合 — つまりドラッグを取り除くと活動自体が根本的に変質したり成立しなくなったりする場合 — に限り、ドラッグのみのインターフェイスを明示的に認めています。ジェスチャー描画アプリケーションや署名取得ウィジェットは典型例です。ただし、この例外は意図的に範囲が狭く設定されています。日常的なUIパターン(スライダー、ソート可能リスト、リサイズ可能なカラムなど)の多くは、本質的なドラッグシナリオとは見なされません。

なぜ重要か

運動障害は世界人口のかなりの割合に影響を与えています。世界保健機関(WHO)によると、世界中で13億人以上、すなわち世界人口のおよそ16%が何らかの障害とともに生活しており、その中でも運動・身体障害は最も一般的なカテゴリの一つです。本態性振戦、パーキンソン病、反復性ストレス障害、片麻痺、脊髄損傷、四肢の差異などの状態は、ポインタボタンを押し続けながらポインタを正確に動かすことを困難または不可能にします。

手の震えがあるユーザーにとって、スライダーのつまみをトラックの端から端までドラッグする操作は、単に不便というだけでなく、まったく信頼できない場合があります。ポインタが滑ってしまったり、ドラッグが操作の途中でキャンセルされたり、要求される精度が震えのある手で達成できる範囲を超えていたりするのです。こうしたユーザーは、クリックベースの代替手段やキーボード操作、スイッチアクセスデバイスに頼ることが多くなります。もしある機能への唯一の経路がドラッグジェスチャーであれば、その機能全体が事実上利用不可能になります。

具体的なシナリオ: デュアルハンドルのレンジスライダーで価格帯フィルターを実装したECサイトの商品ページを考えてみましょう。細かな運動制御に制限のあるユーザーが価格帯を絞り込もうとしても、どちらのハンドルも狙った位置まで安定してドラッグできません。ポインタが流れてしまい、ハンドルが誤った値にスナップし、フラストレーションから作業を断念してしまいます。同じフィルターにスライダーと並んで2つの数値テキスト入力欄が用意されていれば、そのユーザーは希望する最小値と最大値を入力して送信するだけで済みます。この1つの追加によって、開発コストをほとんど増やすことなく、利用不可能だった機能が完全に利用可能なものへと変わります。

運動障害にとどまらず、厳しい環境下でタッチスクリーンを使うユーザー — 公共交通機関で手すりをつかんでいる、手袋をしている、スタイラスを使っているなど — も単一ポインタの代替手段の恩恵を受けます。認知アクセシビリティの観点からも、より単純なクリックベースのインタラクションは、空間的メタファーを理解しつつ物理的な精度を維持する必要があるドラッグ&ドロップ操作に比べて、認知負荷を軽減します。

ユーザビリティとSEOの観点からも、インタラクティブなコントロールを単純なポインタ操作で利用可能にすることは、よりクリーンなコンポーネントアーキテクチャと適切なセマンティックマークアップにつながり、その結果として支援技術や検索エンジンクローラーによる発見性が向上する傾向があります。

関連する axe-core のルール

WCAG 2.5.7 は手動テストの達成基準です。執筆時点では、axe-core にはこの達成基準の違反を自動的かつ確実に検出できるルールは含まれていません。その理由は、この達成基準の性質に根ざしています。自動ツールは、ある要素にドラッグイベントリスナーが存在することは検出できますが、ドラッグを伴わない代替手段が存在するかどうか、その代替手段が同じ機能をカバーしているかどうか、あるいはドラッグが本質的かどうかを確実に判断することはできません。これらの判断には、インタラクションデザインに対する人間の評価が必要です。

  • 手動監査 — ドラッグ&ドロップのアフォーダンス: テスターは、ページ内のすべてのコンポーネントについて、mousedown/mousemove/mouseup のシーケンスや、それに相当するタッチイベント(touchstart/touchmove/touchend)に反応するものを特定し、それぞれがドラッグを伴わない単一ポインタ押下で操作可能な代替メカニズムを提供しているか検証しなければなりません。また、HTML5 の draggable 属性と、それに関連する dragstart/drop イベントリスナーも、ドラッグ依存の機能を示すシグナルとして確認すべきです。
  • 手動監査 — ポインタイベントの検査: ブラウザの DevTools によるイベントリスナーの検査や、Accessibility Insights for Web(2.5.7 用の手動チェックリストを含む)のようなアクセシビリティ監査ツールを用いて、コンポーネントのポインタイベントハンドラーを調べ、そのコンポーネントの値の全範囲や位置変更機能が、継続的なポインタ移動なしに到達可能であることを確認します。
  • 自動化では検出できない理由: 自動スキャナーは、ある <div>dragstart リスナーがあることは検出できますが、近くにある「Move up」とラベル付けされたボタンをクリックすることで、要件を満たす代替手段が提供されているかどうかを知ることはできません。これは、UI 要素間の関係性や機能的な同等性を理解する必要があり、現時点の静的または実行時 DOM 解析ツールの能力を超えています。

テスト方法

  1. 自動スキャンによるベースライン: axe DevTools や Lighthouse をページに対して実行し、関連するポインタや入力モダリティの問題を洗い出します。axe のルールで 2.5.7 に直接対応するものはありませんが、2.5.x のルールで検出された問題を確認することで有用な文脈が得られます。キーボードサポートが不十分だと axe によって指摘されたコンポーネントは、ドラッグのみのパターンと重なっていることが多いため、特に注意しておきます。
  2. すべてのドラッグ可能コンポーネントの特定: Chrome DevTools を開き、Elements パネルに移動して Event Listeners タブを使い、dragstartdragdroppointermovemousemovetouchmove ハンドラーを探します。あるいは、ページソース内で draggable 属性や .addEventListener('dragstart' のような JavaScript パターンを検索しても構いません。ドラッグを必要とするすべてのコンポーネントをリストアップします。
  3. 各ドラッグ可能コンポーネントの代替手段テスト: 特定した各コンポーネントについて、ドラッグを使わずに単一ポインタのクリックやタップだけで同じ結果を得られるか試します。スライダーであれば、目的の位置をトラック上で直接クリックします。ソート可能リストであれば、移動ボタンやコンテキストメニューのオプションを探します。リサイズ可能なパネルであれば、ダブルクリックやクリックベースのコントロールを探します。代替手段が存在しない場合、その達成基準は不適合となります。
  4. キーボード操作の確認(第二のシグナル): すべてのドラッグ可能コンポーネントをキーボードだけでテストします(Tab でフォーカス、矢印キー、Enter/Space)。キーボードサポートは WCAG 2.1.1 の対象ですが、堅牢なキーボードサポートがある場合、多くはドラッグ以外の代替手段も存在するため、有用な確認ステップになります。NVDA + Firefox、VoiceOver + Safari(macOS/iOS)、JAWS + Chrome などを用いて、ポインティングデバイスなしでもコンポーネントの全機能が操作可能であることを確認します。
  5. タッチデバイスでの検証: モバイルデバイス上、または Chrome DevTools のデバイスエミュレーションをタッチモードで使用し、スワイプ&ホールドなしのタップジェスチャーだけで同じタスクを完了できるか試します。すべての機能について、単一タップやターゲットへのタップ操作だけで十分であることを確認します。
  6. 結果の記録: テストした各コンポーネントについて、要件を満たす単一ポインタ代替手段が存在するか、その代替手段が機能の全範囲をカバーしているか、ドラッグ操作が本質的と見なされる可能性があるかを記録します。WCAG 2.5.7 用の構造化されたガイドとして、Accessibility Insights for Web の手動テストチェックリストを利用します。

修正方法

トラッククリック非対応のレンジスライダー — 不適切

<!-- Slider that only responds to drag on the thumb;
     clicking the track does nothing -->
<div class='slider-container'>
  <div class='slider-track'>
    <div class='slider-thumb'
         id='priceSlider'
         onmousedown='startDrag(event)'>
    </div>
  </div>
</div>

トラッククリックと数値入力対応のレンジスライダー — 適切

<!-- Native <input type='range'> provides drag, click-on-track,
     and keyboard support natively. A numeric input offers an
     additional single-pointer alternative. -->
<label for='priceRange'>Maximum price: <span id='priceValue'>500</span> TL</label>
<input type='range'
       id='priceRange'
       name='priceRange'
       min='0'
       max='1000'
       value='500'
       step='10'
       aria-valuemin='0'
       aria-valuemax='1000'
       aria-valuenow='500'
       oninput='document.getElementById("priceValue").textContent = this.value;
                document.getElementById("priceNumber").value = this.value;'>
<label for='priceNumber'>Or enter a value:</label>
<input type='number'
       id='priceNumber'
       name='priceNumber'
       min='0'
       max='1000'
       value='500'>

代替手段のないドラッグ&ドロップ式ソートリスト — 不適切

<!-- Items can only be reordered by dragging.
     No move buttons or keyboard reordering exist. -->
<ul id='taskList'>
  <li draggable='true' ondragstart='handleDrag(event)' id='item1'>Task One</li>
  <li draggable='true' ondragstart='handleDrag(event)' id='item2'>Task Two</li>
  <li draggable='true' ondragstart='handleDrag(event)' id='item3'>Task Three</li>
</ul>

移動ボタン付きドラッグ&ドロップ式ソートリスト — 適切

<!-- Drag-and-drop is preserved for users who can use it.
     Move Up / Move Down buttons provide a single-pointer
     (and keyboard-accessible) alternative for every item. -->
<ul id='taskList' aria-label='Sortable task list'>
  <li draggable='true'
      ondragstart='handleDrag(event)'
      id='item1'>
    <span>Task One</span>
    <button type='button'
            onclick='moveItem("item1", -1)'
            aria-label='Move Task One up'>
      &uarr; Move Up
    </button>
    <button type='button'
            onclick='moveItem("item1", 1)'
            aria-label='Move Task One down'>
      &darr; Move Down
    </button>
  </li>
  <li draggable='true'
      ondragstart='handleDrag(event)'
      id='item2'>
    <span>Task Two</span>
    <button type='button'
            onclick='moveItem("item2", -1)'
            aria-label='Move Task Two up'>
      &uarr; Move Up
    </button>
    <button type='button'
            onclick='moveItem("item2", 1)'
            aria-label='Move Task Two down'>
      &darr; Move Down
    </button>
  </li>
</ul>

代替手段のないリサイズ可能スプリットペイン — 不適切

<!-- The divider can only be repositioned by dragging.
     No percentage input or preset-size buttons exist. -->
<div class='split-pane'>
  <div class='pane pane-left' id='leftPane'>Content A</div>
  <div class='divider'
       onmousedown='startResize(event)'
       aria-hidden='true'></div>
  <div class='pane pane-right' id='rightPane'>Content B</div>
</div>

プリセットサイズボタン付きリサイズ可能スプリットペイン — 適切

<!-- The divider still supports dragging, but preset-layout
     buttons allow single-pointer repositioning. The divider
     is also keyboard-focusable with arrow-key support. -->
<div class='split-pane-wrapper'>
  <div class='split-controls' role='group' aria-label='Panel size presets'>
    <button type='button' onclick='setSplit(25)'>25 / 75</button>
    <button type='button' onclick='setsplit(50)'>50 / 50</button>
    <button type='button' onclick='setSplit(75)'>75 / 25</button>
  </div>
  <div class='split-pane'>
    <div class='pane pane-left' id='leftPane'>Content A</div>
    <div class='divider'
         role='separator'
         tabindex='0'
         aria-label='Resize panels'
         aria-valuenow='50'
         aria-valuemin='10'
         aria-valuemax='90'
         onmousedown='startResize(event)'
         onkeydown='resizeWithKeys(event)'>
    </div>
    <div class='pane pane-right' id='rightPane'>Content B</div>
  </div>
</div>

よくある間違い

  • スライダーをクリック非対応のカスタム <div> ベースコンポーネントとして実装すること。つまみ要素のドラッグのみに依存し、値をクリック位置にジャンプさせるためのトラック要素への click イベント処理を行っていないケースです。
  • ドラッグ&ドロップによるファイルアップロードだけで十分だと想定すること。ドロップゾーンと並行して必須のフォールバックとして、目に見えるクリック可能なファイル選択ボタン(<input type='file'>)を提供していないケースです。
  • 「本質的」例外の適用範囲を広げすぎること。たとえば、ソート可能なToDoリストやかんばんボードについて、Move Up/Down ボタンでユーザーのニーズを機能損失なく完全に満たせるにもかかわらず、「本質的なドラッグ」と見なしてしまうケースです。
  • 単一ポインタの代替ではなくキーボード代替のみを提供すること。WCAG 2.5.7 がキーボードサポートだけで満たされると誤解しているケースです。この達成基準は単一ポインタによる経路を明示的に要求しており、キーボードのみの解決は 2.1.1 を満たすものであって、2.5.7 を満たすものではありません。
  • 移動ボタンや数値入力をホバー状態やセカンダリメニューの背後に隠してしまうこと。それらを表示するために、ドラッグインタラクションや複雑なポインタシーケンスが必要となり、代替手段のアクセシビリティを事実上無効にしてしまうケースです。
  • タッチデバイスを軽視すること。デスクトップマウスでのみドラッグ代替をテストし、その後、ドラッグジェスチャーの挙動や代替手段がデスクトップ実装と大きく異なり得るタッチスクリーンユーザーに対してそのまま提供してしまうケースです。
  • CSS でスライダートラックに pointer-events: none を指定すること。ドラッグ中の誤クリックを防ぐ意図で行った結果として、2.5.7 が要求するトラッククリックの代替手段を意図せずブロックしてしまうケースです。
  • 埋め込み地図やカスタムキャンバスベースの可視化における地図のパン/ドラッグ操作に代替手段を提供しないこと。方向矢印ボタンのクリックや座標の入力など、単一ポインタの代替手段で十分対応できるにもかかわらず、それを用意していないケースです。
  • 単一ポインタの代替手段自体をドラッグ&ドロップターゲットとして実装してしまうこと。たとえば、「ここにドロップ」と表示されたゾーンを作るものの、利用には依然としてドラッグが必要であり、ボタンやテキスト入力といった本質的に異なるインタラクションモデルを提供していないケースです。
  • ドラッグ可能コンポーネントの値の全範囲について代替手段をテストしないこと。スライダーがトラック上のいくつかのプリセット位置にしかクリックで移動できず、ドラッグ版では連続値をサポートしている場合、代替手段は完全なものとは言えません。

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

トルコの大統領通達 2025/10は、2025年6月21日付官報第32933号で公布され、デジタルサービスに関する包括的な国家アクセシビリティ枠組みを確立しています。この通達は、対象組織に対して Web Content Accessibility Guidelines への準拠を求めており、特にレベルAA準拠を、家族・社会サービス省(Aile ve Sosyal Hizmetler Bakanlığı)が発行する公式認証マークであるErişilebilirlik Logosu(アクセシビリティロゴ)取得の基準として明示的に参照しています。

WCAG 2.5.7 は、WCAG 2.2 で導入されたレベルAAの達成基準として、アクセシビリティロゴの取得および維持に必要な要件の範囲に含まれます。ドラッグ&ドロップインタラクションに依存する組織 — 商品フィルタリングスライダーやソート可能なウィッシュリストを備えたECプラットフォーム、ポートフォリオ管理ダッシュボードを持つ銀行アプリケーション、日付範囲セレクターを備えた旅行代理店の予約ツールなど — にとって、2.5.7 に不適合であることは、認証取得への直接的な障壁となります。

大統領通達 2025/10 の対象となる組織は、トルコのデジタル経済の広範なセクターに及びます。すなわち、中央および地方レベルの公的機関・政府機関、銀行規制監督庁(BDDK)の規制下にある銀行および金融サービス提供者、トルコ国内で事業を行うECプラットフォーム病院および民間医療サービス提供者20万件以上の加入者を有する通信事業者旅行代理店および民間輸送会社、そして国民教育省(Milli Eğitim Bakanlığı — MoNE)に認可された私立学校などです。

これらの組織にとって、ドラッグインタラクションに対する単一ポインタ代替手段を提供しないことは、単なる技術的な不備ではなく、認証取得を妨げ、規制当局からの監視対象となり、運動障害のある多くのユーザーを排除しかねないコンプライアンス上のギャップです。トルコの障害者統計は世界的な傾向を反映しており、微細な運動制御に影響を及ぼす状態を抱える住民は数百万人に上ります。ドラッグジェスチャーのみに依存するデジタルサービスは、この人々にとって不要な障壁を築くことになります。

実務的には、Erişilebilirlik Logosu の取得を目指す組織は、アクセシビリティ監査チェックリストに WCAG 2.5.7 を含め、ドラッグ機能を備えたすべてのインタラクティブコンポーネントについて、要件を満たす代替手段があるかを確認し、適合性に関する判断 — 本質性の例外に関する主張も含む — をアクセシビリティ声明(Erişilebilirlik Beyanı)の一部として文書化すべきです。この声明は、通達により対象組織に対して公開と最新状態の維持が求められています。