How to Style File Inputs with ::file-selector-button
Styling native file upload buttons has historically required complex
hacks involving hidden inputs and custom labels. The CSS
::file-selector-button pseudo-element solves this by
allowing developers to style the button inside an
<input type="file"> directly using standard CSS
properties. This guide covers how the pseudo-element works, standard
implementation methods, state handling, and browser compatibility.
What Is ::file-selector-button?
When you render an <input type="file"> element,
browsers generate a compound UI component containing two main parts: a
button (typically labeled "Choose File" or "Browse...") and a text label
indicating the selected file name or "No file chosen."
The ::file-selector-button pseudo-element specifically
targets and isolates that internal button, leaving the accompanying text
label untouched.
Basic Implementation
You can apply standard box model, typography, and color properties to
::file-selector-button just like a regular
<button> element.
input[type="file"]::file-selector-button {
background-color: #0284c7;
color: #ffffff;
border: none;
border-radius: 4px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
cursor: pointer;
margin-right: 12px;
transition: background-color 0.2s ease-in-out;
}This replaces the operating system's default button appearance with your custom styles while preserving the native file-picker functionality.
Adding Interactive States
Interactive pseudo-classes such as :hover,
:active, and :focus chain directly with
::file-selector-button to provide user feedback.
input[type="file"]::file-selector-button:hover {
background-color: #0369a1;
}
input[type="file"]::file-selector-button:active {
background-color: #075985;
}When handling disabled states, style the button based on the input's
:disabled condition:
input[type="file"]:disabled::file-selector-button {
background-color: #cbd5e1;
color: #64748b;
cursor: not-allowed;
}Styling the Remaining File Text
The ::file-selector-button only affects the button
portion. To style the "No file chosen" text or selected filename, apply
styles directly to the parent input selector:
input[type="file"] {
font-family: sans-serif;
font-size: 14px;
color: #475569;
}Browser Support and Legacy Prefixes
The ::file-selector-button is part of the CSS
Pseudo-Elements Module Level 4 and enjoys universal support across all
modern evergreen browsers (Chrome 89+, Edge 89+, Firefox 82+, and Safari
14.1+).
Prior to standardization, browsers implemented their own vendor-prefixed pseudo-elements:
- WebKit/Blink:
::-webkit-file-upload-button - Gecko:
::-moz-range-thumb(for ranges) or custom shadow DOM components - Internet Explorer/Edge (Legacy):
::-ms-browse
For modern web development, vendor prefixes are no longer necessary
unless you must support legacy versions of Safari or Internet Explorer.
Writing standard ::file-selector-button declarations is
sufficient for cross-browser styling.