トピックを検索
ファイルを選ぶボタンがないドラッグ&ドロップのアップロード欄
経費申請フォームの領収書欄はドラッグ&ドロップか枠のクリックでしかファイルを受け付けず、Tabで届くものもボタンとして読まれるものもない
zone.addEventListener('drop', dropFiles); 問題
ドラッグできない人や、キーボードとスクリーンリーダーの利用者は領収書を添付できず、申請を送れない
経費申請のフォームで、金額の次に領収書を添付します。領収書欄は点線の枠で、アップロードの矢印と「ここに領収書をドラッグ&ドロップ」という文言があります。マウスでフォルダーからPDFをドラッグし、枠の上で離すと、枠の下にファイル名が出ます。「金額」の欄からTabキーを押すと、フォーカスは「申請する」へ直接移ります。枠の中にはフォーカスできるものも、押せるボタンもありません。スクリーンリーダーは「ここに領収書をドラッグ&ドロップ」を1行の文として読みます。スマートフォンでは領収書は別のアプリにあるため、ドラッグするには、ファイルを持ったままブラウザーへ切り替える必要があり、そもそもできない端末もあります。
同じ枠に「またはクリックしてファイルを選択」と書かれ、枠のどこをクリックしてもファイル選択が開くこともよくあります。マウスの利用者は問題に気付きません。それでもTabキーは枠を飛ばし、Enterキーを押しても何も起きず、スクリーンリーダーは文言を文として読むだけで、押せるものだと伝えるロールはありません。
枠は、スクリプトでイベントを受け取る div です。1つ目の形では、受け取るのはドロップだけです。ファイルを追加するには、ファイルを押し、運び、離すというドラッグの動作が必要です。WCAG 2.5.7は、ドラッグでできる操作を、1回のクリックやタップだけでもできるようにすることを求めています。その方法がない機能は失敗例F108に当たり、この枠にはその方法がありません。キーボードではフォルダーからページへファイルを運べず、枠の中にフォーカスできるものもないため、キーボードからは領収書を一切追加できず、2.1.1も満たしません。
2つ目の形では、枠の中に hidden 属性で隠したfile inputがあり、枠がクリックされるとスクリプトが click() で開きます。1回のクリックでファイルを追加できるので2.5.7は満たしますが、クリックを受けるのは相変わらず div です。Tabの順序に入らず、EnterキーもSpaceキーも効かないため、2.1.1を満たしません。クリックで動くのでコントロールですが、ロールも名前もありません。スクリーンリーダーは文言を文として読み、押せるものがあるとは伝えないため、4.1.2も満たしません。実際に働くfile inputは誰からも隠されているので、代わりになりません。
経費の申請、応募、問い合わせでは、アップロードしないと送信できないことがよくあります。ドロップしか受け付けない枠が1つあるだけで、フォーム全体が止まります。ドラッグはできても時間がかかる人も、同じ問題で手間取ります。フォルダーとフォームを画面に並べ、枠の中に正確に落とさなければならないからです。
10グループ中4グループに影響
- 全盲 (影響あり)
- 弱視 (影響あり)
- 色覚 (影響なし)
- ろう (影響なし)
- 難聴 (影響なし)
- 発話 (影響なし)
- 手の操作 (影響あり)
- 筋力・可動域 (影響あり)
- 認知 (影響なし)
- 光過敏 (影響なし)
- 手の操作が限られる キーボード、スイッチ、音声操作の利用者は、フォルダーからページへファイルをドラッグできません。Tabも枠に止まらないため、領収書を添付できません。
- 視覚を使わない スクリーンリーダーの利用者には、枠の文言がただの文として聞こえ、押せるボタンはありません。見えない枠をめがけてドラッグすることもできません。
- 筋力や可動域が限られる 手のふるえや握力の弱さがある人は、運ぶ途中でファイルを落としたり、枠の手前で離したりして、フォルダーからやり直しになります。
- 視覚が限られる 拡大鏡を使っていると、フォルダーと枠が同時に画面に収まることはまれで、スクロールする画面の中をファイルを持ったまま運ぶことになります。
自動チェックに見えるのは、div と段落、2つ目の形ではそれに加えて誰からも隠されたfile inputだけです。隠されたinputにラベルを求めるルールはありません。クリックとドロップのイベントはマークアップではなくスクリプトにあるため、枠がコントロールだと示すものもありません。EaseWebの診断は、自身でドロップを受け取る枠、display: none、visibility: hidden、hidden 属性のどれかで隠したfile inputを囲む枠、ファイルのドラッグやドロップを求める文言のある点線や破線の枠を探し、中にTabで届くものがなく、横にもfile inputやファイルを選ぶ・アップロードするボタンがなければ、確認の手がかりとして報告します。フレームワークがルートにまとめて付けたイベントは見えず、ページの別の場所にあるボタンが同じinputを開くこともあるため、1つずつ人が確認します。AIにドロップゾーンのアクセシビリティ改善を頼むと、一部のアップロード用ライブラリーと同じように、枠に tabindex="0" を付けることがよくあります。枠はフォーカスを受けるようになりますが、ロールも名前もないためスクリーンリーダーはほとんど何も読まず、キー操作の処理も書かない限りEnterキーでは何も起きません。診断は、このような枠も確認の手がかりとして報告します。
試してみる
ファイルを枠へドラッグして、領収書を添付してみましょう。次に、マウスを使わずにTabでも試してみましょう
問題1: フォームの下のファイルか、自分のパソコンのファイルを枠へドラッグします。次に「金額」からTabキーを押すと、フォーカスは「申請する」へ飛び、クリックでもキーでもファイルを追加できません。
問題2: 枠をクリックすると、ファイル選択が開くようになりました。それでもTabキーは枠を通り過ぎ、押せるものがあることは、下の欄の読み上げに一度も出てきません。
修正を適用します。 Tabキーが枠の中のコントロールで止まり、EnterキーかSpaceキーでファイル選択が開きます。ドロップもそのまま使えます。
問題あり 修正できますか?
ここに領収書をドラッグ&ドロップ
スクリーンリーダーの読み上げ:
(Tabでフォームを移動してください)
修正方法
ドロップは残し、ファイルを選ぶボタンも置く
ドロップしか受け付けない枠
<div class="field"> <span class="field-label" id="receipts-label">領収書</span> <div class="drop-zone"> <p>ここに領収書をドラッグ&ドロップ</p> </div> <ul class="file-list"></ul></div>問題点3点
- ファイルを入れる方法はドロップだけです。
- 枠の中に、フォーカスできるものがありません。
- クリックでもキーでも、ファイルを追加できません。
隠したinputを開く「ファイルを選択」ボタン
<div class="field"> <span class="field-label" id="receipts-label">領収書</span> <div class="drop-zone"> <p>ここに領収書をドラッグ&ドロップ、または</p> <button type="button" class="choose" aria-describedby="receipts-label">ファイルを選択</button> <input type="file" id="receipts" multiple hidden> </div> <ul class="file-list"></ul></div>修正の手順3ステップ
- 枠の中に、HTML標準の「ファイルを選択」ボタンを置きます。ブラウザーがTabの順序に入れ、EnterキーやSpaceキーで押せるようにし、ロールも付けます。
- 名前はボタン自身の文字にし、欄のラベルを説明にします。「ファイルを選択、ボタン、領収書」のように読まれます。
- inputを開くクリックを枠からボタンへ移し、枠の
cursor: pointerを外します。1回のクリック、タップ、キー操作でファイル選択が開き、音声操作では「ファイルを選択をクリック」と言えます。
これで二つの修正前の例はどちらも直り、2.1.1、2.5.7、4.1.2を満たします。inputは hidden で隠したままです。現在のブラウザーでは、この状態でも click() でファイル選択が開き、必要な操作はすべてボタンでできます。ドロップはこれまでどおり使えます。
この方法を選ぶ理由:ジェスチャーは近道にし、唯一の方法にしない
3つとも基準を満たし、どれもドロップを残します。特に理由がなければボタンを使ってください。どのブラウザーでもページ自身の文言を表示でき、フォーカスの枠もフォーカスを受ける要素そのものに出る唯一の方法で、必要なスクリプトは1行です。file inputそのものはスクリプトも隠す要素も要らないため、簡素なフォームや、フォームを使う前にスクリプトを実行できないページに向いています。ただし、ボタンの文字と、ファイルが選ばれていないという横の表示はブラウザーが自身の言語で書くため、ドロップしたファイルと表示を合わせる必要があります。隠したinputに重ねるlabelもスクリプトは要らず、デザインどおりの見た目にできますが、フォーカスの枠とフォーカスを受ける要素が別々で、CSSのセレクターでつながっているだけです。マークアップを変えると、ほかは何も壊れないまま枠だけが消えることがあります。
ドロップは残してください。フォルダーをフォームの横に開いている人には速い方法で、ボタンがあればドロップは唯一の方法ではなく近道になります。枠全体のクリックも、ボタンがある限り、マウス用の大きな的として残してかまいません。ただし、枠のクリックの処理ではボタンから始まったクリックを無視してください。そうしないと、ファイル選択を2回開こうとすることがあります。
ファイルが入った後の動きは、いくつかの小さな判断で決まります。
- 追加したことを伝える:ドロップした後やファイル選択を閉じた後は、枠にファイルを一覧表示し、「2件のファイルを追加しました:taxi-receipt.pdf、hotel-invoice.pdf」のようにステータス領域でも伝える。ファイル選択を閉じるとフォーカスはボタンに戻るため、伝えないとスクリーンリーダーの利用者は自分で探すことになる。詳しくは「画面に出ても読み上げられないステータスメッセージ」を参照。
- ファイルの削除:一覧の各ファイルに、ファイル名を含む名前の削除ボタン(「taxi-receipt.pdfを削除」)を付け、削除後は次のファイルか「ファイルを選択」へフォーカスを移す。
- 必須のアップロード:
hiddenで隠したfile inputには、ブラウザーが自身のメッセージを出すためにフォーカスを移せないため、requiredを付けると、何も表示されないままフォームが止まることがある。ファイルの有無は自分で確認し、メッセージをボタンの横に置いて関連付ける。詳しくは「直し方がわからないフォームエラー」を参照。 - スマートフォン:ボタンは同じinputを開くため、カメラ、写真ライブラリー、ファイルなど、端末自身の選択肢がそのまま出る。
accept="image/*,.pdf"で選べる種類を絞れる。同じ種類を枠の文言にも書き、エラーで初めて知ることがないようにする。 - アップロード用ライブラリー:Dropzone.jsは枠全体をクリックできるようにし、react-dropzoneは枠そのものをTabで止まるようにする。それぞれ何を支援技術に伝えているかを確認し、枠しかない場合は本物のボタンを加える。
デザインの案
ファイルを落とす場所はどんな形でもよい。ボタンさえあれば
領収書を添付する場所を5通りに描きました。自分のパソコンのファイルをそれぞれにドラッグしてから、マウスを使わずにTabでも試してください。4つにはファイル選択を開くボタンがあり、1つはドロップでしかファイルを受け取りません。
デザインファイルで
- ファイルを選ぶボタンを、言葉付きで、何もしていない状態から描く。ドロップを促す言葉だけにしない。
- 添付する場所を、何もしていない状態と、ファイルを上に持ってきた状態の2通りで描く。
- ボタンにフォーカスの枠を付けて描く。ファイルを追加した後の一覧も描き、各ファイルに「削除」ボタンを付ける。
- スマートフォンのレイアウトも描く。ドラッグで入れられないため、ボタンがファイルを追加する唯一の方法になる。
合格
- 領収書添付ボタンとファイルのチップ 枠はありません。クリップの付いた控えめな枠線のボタンだけで、追加したファイルはそれぞれ削除用の×付きのチップになります。欄のどこにファイルを落としても受け取るので、ドロップは近道として残り、フォームも小さいままです。ボタンの青い文字は白に対して6.09:1です。
ここに領収書をドロップ、または
文の中の「参照」ボタン 破線のない淡い青の面で、文の中の1語がボタンです。「参照」に下線を引き、サイトの青の太字にしています。面の色に対して5.47:1です。クリックとTabで止まるのはこの語だけなので、フォーカスの枠も語にぴったり付きます。何を選ぶのかが分かる名前(「領収書を参照」など)にします。- ファイルを持ってきたときだけ現れる落とし先 何もしていないときは「領収書を追加」ボタンだけが見え、ファイルをドラッグしてきたときだけ、カード全体に青い縁と「ドロップして添付」の落とし先が重なります。画面は落ち着いたまま、落とし先はできるだけ大きく、ボタンの位置も変わりません。
- 領収書
- taxi.pdf
- lunch.jpg
追加済みの領収書の横に「領収書を追加」タイル 追加済みの領収書を小さな紙のタイルで並べ、最後のタイルを、プラスと「領収書を追加」の言葉が入った破線のタイルにします。このタイルがボタンなので、タップかEnterキーでファイル選択が開き、ファイルを落としても受け取ります。言葉は残してください。プラスだけでは、目に見えない名前が必要になります。
不合格
- 領収書はまだありません「どこにでもドロップ」とだけ書いた空の状態WCAG 2.5.7 親しみやすいイラストに「領収書はまだありません」と「このページのどこにでも領収書をドロップできます」。最もすっきりした空の状態で、ドロップも実際に使えます。しかし押せるものが何もないため、Tabでは何も見つからず、クリックしても何も起きず、ほとんどのスマートフォンでは領収書を追加する方法がまったくありません。
修正の確認
5項目
確認方法: キーボード、スクリーンリーダー、マウス、タッチ、音声入力
OS、ブラウザーと支援技術のバージョン、ビルド、実施日、各手順の実際の結果を記録してください。アップロードのコンポーネントやライブラリーを変更した際は、再度確認します。
スクリーンリーダーでの aria-describedbyの読まれ方
制限
このサンプルは、どのアプリケーションでも同じ結果になることを保証するものではありません。カードやリストの項目をドラッグで動かすことは「マウスでしか動かせないドラッグ&ドロップのボード」で、アップロードした写真の内容を尋ねることは「代替テキストを尋ねない画像のアップロード」で扱っています。大きなファイルのアップロードの進み具合を示す表示には別の配慮が必要です。「スクリーンリーダーで読めないプログレスバーとメーター」を参照してください。ファイルの貼り付けやフォルダーごとのアップロードは、ここでは扱いません。ファイル選択の画面はOSのもので、キー操作やスクリーンリーダーの対応はOSによって異なります。対象とする支援技術で、操作全体を確認してください。
よくある問題を再現した学習用のサンプルです。実在のクライアントの診断結果ではありません。コードは出発点となる実装例のため、実際の製品でも確認してください。ここでは支援技術でのテスト結果は報告していません。
EaseWebのサービス
修正した問題を、次のリリースで再発させない
このガイドのような修正方法を、コーディングエージェントが従うルールと、CIのチェックに組み込みます。あわせて定期的に、キーボードとスクリーンリーダーで手動の再テストを行います。