File upload
A file upload lets someone choose a file from their device or drop one onto a target zone. The chosen file name, size and progress are part of the control.
<input type="file">Also called Drop zone, File picker, Attachment.
Drop a PDF or image here, or browse
Up to 10 MB
No file chosen yet.
Drop a file onto the zone, or click Choose file. The name of the selected file appears below. Tab to the button and press Enter to open the picker.
For designers
File upload is the bridge between your form and someone's disk. Dropbox, expense apps and job applications all need a clear place to put a PDF or photo, then confirmation that the right file was chosen.
The cost is failure modes. Wrong type, file too large, upload interrupted and mobile browsers that handle cameras differently all need copy and recovery. A plain button that opens the picker is enough for a single optional attachment. A marked drop zone earns its space when files are the main action on the screen.
State the limits before someone picks. Max size and accepted types belong in helper text under the zone, not only in an error after upload fails. Ten megabytes and PDF or image sets expectations early.
When to use a file upload
Use a file upload when
- Someone must attach a document, image or other file from their device
- Drag and drop onto a marked area is faster than hunting through folders
- You need to show the file name and upload progress before submit
Reach for something else when
- The value is plain text someone can paste, like a URL. Use a text field instead.
- Someone picks one file from a list you already host. Use a select instead.
- The upload is really a camera capture on mobile only. Use a button that opens the camera instead.
- Several unrelated fields belong in one compact row. Use a text field with an attach action beside it instead.
Variants
Attach invoice
PDF only
Uploaded
- receipt-march.pdfDone
- scan-02.pngUploading…
A compact row for one attachment in a form, and a multi-file list after upload.
Drop zone. A dashed border and short instruction text. The whole area opens the picker on click.
Button only. A compact Upload or Attach button in a form row. Fits when the file is secondary to other fields.
With file list. After select, show each file as a row with name, size, progress and remove.
How to build a file upload
Use a native file input. Hide it visually if you want a custom button or drop zone, but keep it in the DOM and associate it with a label.
<label for="receipt">Receipt</label>
<div
role="button"
tabindex="0"
aria-controls="receipt"
aria-label="Drop a file or browse"
>
Drop a PDF or image here
</div>
<input
id="receipt"
type="file"
name="receipt"
accept=".pdf,image/*"
hidden
/>
<button type="button">Choose file</button>
<p aria-live="polite">No file chosen</p>
Clicking the zone or button triggers input.click(). On change, read files[0] and update the live region with the name. For drag and drop, call preventDefault on dragover and read dataTransfer.files on drop. Keyboard users need Enter or Space on the zone to open the picker.
The file name after select is part of the design. Show it in plain text with size in kilobytes or megabytes. Offer Remove before submit so someone can fix a wrong pick without refreshing the page.
Edge cases
No file selected on submit. Block submit with a field-level error, or treat the field as optional and say so in the label.
Replacing a file. Let someone pick again and overwrite the previous selection, or remove first then add.
Security. Never trust the client extension alone. Validate type and size on the server.
Camera on mobile. The same input can open the camera when accept includes image/* and capture is set. Test on iOS and Android because the picker order differs.
Virus scanning. Enterprise flows sometimes scan after upload. Show Scanning beside the file name, then Done or a quarantine message. People should know the file arrived even when it is not yet available.
Common questions
- Drop zone or button only?
- Offer both when space allows. The zone invites drag and drop. The button reaches keyboard users and anyone who prefers the system file picker. One hidden input can serve both.
- What should accept contain?
- List the MIME types or extensions you truly support, like image/png or .pdf. Broad accept values set false expectations when the server rejects the file.
- How do I show upload progress?
- After select, show the file name and a progress bar or percentage while the upload runs. Replace the bar with a done state or an error with a retry action.
- Can people upload more than one file?
- Add the multiple attribute when the backend accepts several files. Show each file as its own row with its own remove control.
- Is drag and drop accessible?
- Drop zones still need a keyboard path. Click or Enter on the zone should open the same file picker as the button. Do not rely on drag alone.
- What happens when a file is too large?
- Check size before upload when you can. Show a clear message with the limit in megabytes. Do not start the upload and fail halfway.
Last reviewed 27 AUG 2026