⚡IntermediateAdvanced Forms
Advanced File Inputs
Control file uploads with accept, multiple, capture, and drag-and-drop integration.
Overview
The <input type="file"> element lets users select files for upload. Beyond the basics, it has several powerful attributes that control which files are accepted, whether multiple files can be selected, and whether to capture directly from the camera or microphone.
For accessible and custom-styled file inputs, the pattern is to visually hide the native input and trigger it from a styled button. The FileReader API lets you preview files before upload. Drag-and-drop file upload works with the HTML5 Drag and Drop API on a drop zone div.
Key Points
- •accept filters file types: accept="image/*", accept=".pdf,.doc", accept="video/mp4"
- •multiple allows selecting several files at once
- •capture="user" opens front camera; capture="environment" opens rear camera on mobile
- •Files are accessed via input.files (a FileList object)
- •Visually hide the native input and use a <label> or button to trigger it for custom styling
- •URL.createObjectURL(file) creates a temporary URL for file preview without uploading
Examples
Accept and multiple attributes
<!-- Only images -->
<input type="file" name="avatar" accept="image/*">
<!-- Only PDFs and Word docs -->
<input type="file" name="document" accept=".pdf,.doc,.docx">
<!-- Multiple images -->
<input type="file" name="gallery" accept="image/*" multiple>
<!-- Any file, multiple -->
<input type="file" name="attachments" multiple>Mobile camera capture
<!-- Capture photo with front camera (selfie) -->
<input type="file" name="selfie" accept="image/*" capture="user">
<!-- Capture photo with rear camera -->
<input type="file" name="photo" accept="image/*" capture="environment">
<!-- Capture video -->
<input type="file" name="video" accept="video/*" capture="environment">On desktop, capture is ignored and the file picker opens normally.
Custom styled file input with image preview
<style>
.file-btn { display: inline-block; padding: 8px 16px; cursor: pointer; }
#file-native { display: none; }
</style>
<label class="file-btn" for="file-native">Choose Image</label>
<input type="file" id="file-native" name="image" accept="image/*">
<img id="preview" src="" alt="Preview" style="max-width:200px;display:none;">
<script>
document.getElementById('file-native').addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const preview = document.getElementById('preview');
preview.src = URL.createObjectURL(file);
preview.style.display = 'block';
preview.onload = () => URL.revokeObjectURL(preview.src); // free memory
});
</script>Drag-and-drop file zone
<div
id="drop-zone"
style="border: 2px dashed #aaa; padding: 40px; text-align: center;"
ondragover="event.preventDefault()"
ondrop="handleDrop(event)"
>
Drop files here
</div>
<script>
function handleDrop(e) {
e.preventDefault();
const files = e.dataTransfer.files;
[...files].forEach(f => console.log(f.name, f.size));
}
</script>Common Mistakes
- Relying on accept for security validation users can bypass it; always validate on the server
- Not calling URL.revokeObjectURL() after preview causes memory leaks
- Forgetting enctype="multipart/form-data" on the form when uploading files
Note
Always set enctype="multipart/form-data" on any form that contains a file input. Without it, the file content is not sent to the server only the filename.
Exercises
Write HTML to solve each exercise. Use Preview to see it render in a live iframe, then mark as done.
Loading editor…
Completed: 0 / 5 exercises
Knowledge Check
Question 1 of 4