Color and File Inputs
Two more specialized HTML5 input types: type="color" opens the browser or OS's native color picker, and type="file" lets users choose one or more files from their device to upload — both without any JavaScript for the basic case.
input type="color"
<input type="color"> renders a small swatch that, when clicked, opens the browser's (or operating system's) native color picker. Its value is always a lowercase 7-character hex string like #ff0000 — there is no built-in support for RGBA, HSL, or named colors.
color-input.html
<label for="theme-color">Accent color</label> <input type="color" id="theme-color" name="theme-color" value="#3366ff">
input type="file"
<input type="file"> opens the device's native file picker. Selected files aren't directly settable via the value attribute for security reasons — the browser only lets the user choose them interactively, and JavaScript can read (but not fabricate) the resulting FileList.
file-input-basic.html
<label for="resume">Upload your resume</label> <input type="file" id="resume" name="resume">
Restricting File Types with accept
The accept attribute hints to the browser which file types to show or filter for in the picker — by MIME type, file extension, or a general media category. It's a UX convenience, not a security boundary: a determined user can still select any file, so always validate file type and content on the server too.
accept-attribute.html
<!-- By file extension --> <input type="file" name="resume" accept=".pdf,.doc,.docx"> <!-- By MIME type --> <input type="file" name="photo" accept="image/png, image/jpeg"> <!-- By general media category --> <input type="file" name="avatar" accept="image/*"> <input type="file" name="clip" accept="video/*">
accept filter (e.g. by choosing "All Files" in the native dialog on desktop). Never rely on it as your only defense — check the file's actual type and size on the server before trusting it.Selecting Multiple Files
Add the boolean multiple attribute to let the user select more than one file in a single picker interaction.
multiple-files.html
<label for="gallery">Upload photos</label> <input type="file" id="gallery" name="gallery" accept="image/*" multiple>
capture for Mobile Camera Access
On mobile devices, the capture attribute hints that the file input should open the device camera or microphone directly instead of the general file/photo picker. It's commonly paired with accept="image/*" or accept="video/*".
capture-attribute.html
<!-- Prefer the rear ("environment") camera -->
<input type="file" accept="image/*" capture="environment">
<!-- Prefer the front-facing ("user") camera, e.g. for a selfie or avatar -->
<input type="file" accept="image/*" capture="user">Attribute | Applies to | Effect |
|---|---|---|
|
| Filters which file types the native picker suggests |
|
| Allows selecting more than one file at once |
|
| Opens the device camera/mic directly instead of the file browser |
capture is primarily meaningful on mobile devices with a camera. Desktop browsers typically fall back to the standard file picker, so don't build a flow that depends on the camera opening — treat it as a mobile enhancement.type="color"gives a native color picker whose value is always a 6-digit hex string.type="file"opens the native file picker; useacceptto hint at allowed types.Add
multipleto allow selecting several files at once.Add
capture="user"orcapture="environment"to jump straight to the mobile camera.Always validate file type, size, and content on the server — client-side hints are not security.
Reading a Color Value in JavaScript
The color input fires an input event as the user drags the picker (live preview) and a change event when they finalize their choice — useful for live-previewing a color change versus committing it.
color-live-preview.js
const colorInput = document.getElementById('theme-color');
colorInput.addEventListener('input', () => {
document.documentElement.style.setProperty('--accent-color', colorInput.value);
});Reading File Metadata Before Upload
Selected files are exposed as a FileList on the input's files property. Each File object carries metadata (name, size, type) you can inspect client-side — useful for showing a preview or rejecting oversized files before even attempting an upload.
file-metadata.js
const fileInput = document.getElementById('resume');
fileInput.addEventListener('change', () => {
const [file] = fileInput.files;
if (!file) return;
console.log(file.name); // "resume.pdf"
console.log(file.size); // size in bytes
console.log(file.type); // "application/pdf"
const maxSizeBytes = 5 * 1024 * 1024; // 5MB
if (file.size > maxSizeBytes) {
alert('File is too large. Please choose a file under 5MB.');
fileInput.value = '';
}
});Previewing an Image Before Upload
A common pattern combines a file input with FileReader (or URL.createObjectURL) to show a thumbnail preview of a selected image before the user submits the form.
image-preview.js
const avatarInput = document.getElementById('avatar');
const preview = document.getElementById('avatar-preview');
avatarInput.addEventListener('change', () => {
const [file] = avatarInput.files;
if (file) {
preview.src = URL.createObjectURL(file);
}
});URL.createObjectURL() holds a reference in memory until you release it. Call URL.revokeObjectURL(preview.src) once the preview image is no longer needed, especially in single-page apps where the same page stays loaded for a long time.Styling File Inputs
The default file input button is notoriously hard to restyle directly. A common approach hides the native input visually while keeping it accessible, and triggers it from a custom-styled button or label.
styled-file-input.html
<label class="upload-button" for="resume-upload">Choose File</label> <input type="file" id="resume-upload" name="resume" class="visually-hidden">
visually-hidden.css
.visually-hidden {
position: absolute;
width: 1px;
height: 1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
}for/id, clicking the styled label still opens the native file picker, and screen reader users still get an announced, focusable control — the visual hiding doesn't remove it from the accessibility tree.