What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

For a small change, style the native file picker button with ::file-selector-button. For a fully custom-looking trigger, keep the real file input and associate it with a styled label. CSS cannot style the browser-generated filename or “no file selected” text, so display custom filename messaging separately if your design needs it.

Choose the right styling approach

Approach What it changes Key consideration
::file-selector-button The button portion of the native file input Keeps the native control. The browser-generated filename text remains outside CSS.
Styled label and visually hidden input A broader custom presentation Requires an explicitly associated label, keyboard access, and a visible focus cue.
Separate button and JavaScript A custom trigger separate from the input The button needs an accessible name and keyboard operation, and script must invoke the input.

Style the native file picker button

This is the simplest option when the browser’s file input layout is acceptable and you only need to change the button’s appearance.

<label for="resume">Resume</label>
<input id="resume" name="resume" type="file">
input[type="file"]::file-selector-button {
  background: #174ea6;
  border: 0;
  border-radius: 0.35rem;
  color: #fff;
  cursor: pointer;
  font: inherit;
  margin-right: 0.75rem;
  padding: 0.65rem 1rem;
}

input[type="file"]::file-selector-button:hover {
  background: #123d80;
}

input[type="file"]:focus-visible {
  outline: 3px solid #f0a500;
  outline-offset: 3px;
}

::file-selector-button targets the button, not the neighboring filename or empty-state text. MDN notes that the browser generates that text and does not expose it to CSS in its advanced form styling guide.

Create a custom-looking trigger with a label

Use a real file input with an id and a label whose for attribute matches it. The label can be styled as the visible trigger while activating the input.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
<label class="upload-label" for="attachment">Choose a file</label>
<input class="visually-hidden" id="attachment" name="attachment" type="file">
.visually-hidden {
  clip: rect(0, 0, 0, 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

.upload-label {
  background: #174ea6;
  border-radius: 0.35rem;
  color: #fff;
  cursor: pointer;
  display: inline-block;
  padding: 0.65rem 1rem;
}

.visually-hidden:focus-visible + .upload-label {
  outline: 3px solid #f0a500;
  outline-offset: 3px;
}

The focus selector above assumes the input appears immediately before the label. Because the example markup places the label first, reverse their order to use that selector:

<input class="visually-hidden" id="attachment" name="attachment" type="file">
<label class="upload-label" for="attachment">Choose a file</label>

Do not hide the input with display: none or visibility: hidden for this pattern; those techniques remove it from keyboard interaction. The W3C’s labeling guidance explains control-label relationships, and its focus-visible guidance calls for visible keyboard focus.

Rank #2
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Show the selected filename separately

The native input remains the control that opens the device’s file picker. Its selected files are available to web application code through the File API, but its value is not a real local file path. MDN documents these details in its file input reference and guide to using files in web applications.

If you need custom filename text, read the selected file from the input and render a separate message:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
<label for="document">Document</label>
<input id="document" name="document" type="file">
<span id="document-name" aria-live="polite">No file chosen</span>

<script>
  const input = document.querySelector("#document");
  const message = document.querySelector("#document-name");

  input.addEventListener("change", () => {
    message.textContent = input.files.length
      ? input.files[0].name
      : "No file chosen";
  });
</script>

This updates the adjacent message for a single selected file. For a multiple-file input, use the files collection to present all selected names or an appropriate count.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Keep the upload usable without dragging

A drag-and-drop area can supplement file selection, but it should not be the only way to upload. W3C WCAG 2.2 Success Criterion 2.5.7 requires a single-pointer alternative to functionality that uses dragging, unless an exception applies. Keep a selectable file input or equivalent control available; see the WCAG 2.2 standard.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.