CodingLaboratory
Lab Commands
Enter The Lab

Frontend field guide / accessible-file-upload

11 min
Forms, Testing & Production 11 min Updated

Accessible file upload with drag-and-drop enhancement

Create a keyboard-operable file picker with drag-and-drop, validation, upload progress, cancellation, retry, and clear file states.

accessible file uploaddrag and drop uploadupload progress UIfile input UX

What you will build correctly

  • Keep a native file input and treat drag-and-drop as an enhancement.
  • Validate type and size with messages that explain the correction.
  • Represent each file with explicit pending, uploading, success, error, and cancelled states.
01

Start with a labelled native file input

A native file input opens the platform picker, supports keyboard and assistive technology, and works without drag-and-drop. Style a label as the visible action when necessary, but keep the input available and avoid hiding it with display none when that removes expected focus behavior.

Use accept as a picker hint, not a security boundary. The server must inspect the uploaded content, enforce size limits, generate safe filenames, and reject unsupported files regardless of the client declaration.

A labelled multiple-file input
                      <label for="assets">Choose images</label>
<input id="assets" name="assets" type="file" accept="image/png,image/jpeg" multiple aria-describedby="asset-help">
                    
02

Enhance the same region for drag-and-drop

The dropzone should include the visible choose-files action, instructions, accepted formats, and size limit. Highlight dragover without replacing the instructions, and process dropped files through the same validation and upload pipeline as picker files.

Dragging is a pointer convenience, not a required path. Do not make users drag precisely onto a small target, and do not block the browser from opening dropped files outside the intentional dropzone.

03

Give every file a state and available action

List selected filenames, human-readable sizes, and statuses. Pending files can be removed, uploading files may be cancellable, failed files need a reason and retry, and successful files should remain identifiable. Progress bars need accessible names and values.

Avoid announcing progress on every percentage point. Announce state transitions such as upload started, completed, failed, or cancelled, while keeping visual progress available for sighted users.

  • Duplicates are handled predictably.
  • Retry does not create a second list item.
  • Focus stays near the action that changed the file.
04

Test large, invalid, duplicate, and interrupted files

Select files that exceed limits, use unsupported types, drop the same file twice, cancel mid-upload, and disconnect the network. The interface should preserve valid files and explain the next step for each failure instead of resetting the whole queue.

On mobile, verify camera and photo-library choices, long filenames, touch targets, and background interruptions. Upload UX is complete only when recovery paths receive the same attention as the successful animation.

Use the pattern

Study it in working components.

These internal examples connect the guide to standalone HTML, CSS, and JavaScript you can preview, customize, and download.