<input type="file"> lets a user pick one or more files from their device to upload — the only input type where notable, hard-to-fully-restyle native browser UI is involved.
Syntax
<input type="file" name="resume" accept=".pdf,.doc,.docx">
Basic Example
<form action="/upload" method="post" enctype="multipart/form-data">
<label for="resume">Upload Resume</label>
<input type="file" id="resume" name="resume" accept=".pdf">
<button type="submit">Upload</button>
</form>
Browser output: a native "Choose File" button plus a filename display — clicking it opens the operating system's own file picker dialog. Note the required enctype="multipart/form-data" on the parent form.
How It Works
The accept attribute filters which file types the OS dialog suggests/allows, though it's a hint, not a strict security boundary — file type must still be validated on the server, since a determined user can bypass client-side restrictions entirely.
Important Attributes
| Attribute | Purpose |
|---|---|
accept | Restricts (as a UI hint) which file types the picker suggests, e.g. image/* or .pdf |
multiple | Allows selecting more than one file at once |
Real-World Example
<label for="photos">Upload project screenshots</label>
<input type="file" id="photos" name="photos[]" accept="image/*" multiple>
Allowing multiple image uploads at once — note the [] in the name, a common server-side convention (in many backend languages) for receiving an array of files rather than just one.
Common Mistakes
- Forgetting
enctype="multipart/form-data"on the parent<form>— without it, file content is never actually sent - Relying entirely on
acceptfor security, without also validating file type and size server-side - Trying to fully restyle the native "Choose File" button with CSS alone — most designs instead hide the raw input and trigger it via a styled
<label>or button
Best Practices
- Always pair with
enctype="multipart/form-data" - Always re-validate file type and size on the server, regardless of client-side
accepthints - Use the label-triggers-hidden-input pattern for custom styling, keeping the real input accessible
Accessibility Considerations
When hiding the native file input for custom styling, make sure the visible trigger element remains a real, labeled, keyboard-focusable control — hiding it carelessly (e.g. with display: none and no accessible alternative) can make the upload completely unusable for keyboard and screen reader users.
SEO Considerations
No direct ranking effect.
Browser & Modern HTML Notes
The native file picker dialog itself is entirely controlled by the operating system, not the browser or your CSS — this is a deliberate security boundary that can't be worked around.
Mini Practice
- Build a resume-upload field restricted to PDF files, inside a correctly configured
<form>. - Research the label-triggers-hidden-input pattern for styling a file input, and explain why it's accessible when done correctly.