HTMLColor & File Inputs

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

HTML
<label for="theme-color">Accent color</label>
<input type="color" id="theme-color" name="theme-color" value="#3366ff">
Only hex, no transparency
Because the value format is locked to 6-digit hex, you can't natively capture an alpha channel. If you need transparency, you'll need a custom color picker built with JavaScript and a library.
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

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

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 is a UI hint, not validation
A user can bypass the 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

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

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

accept

type="file"

Filters which file types the native picker suggests

multiple

type="file"

Allows selecting more than one file at once

capture

type="file" on mobile

Opens the device camera/mic directly instead of the file browser

Desktop browsers mostly ignore capture
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; use accept to hint at allowed types.

  • Add multiple to allow selecting several files at once.

  • Add capture="user" or capture="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

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

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

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);
  }
});
Revoke object URLs when you're done with them
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

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

CSS
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}
A <label> wrapping the input keeps it fully accessible
Because the label is properly connected to the input via 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.