Skip to main content

How to Style File Input in CSS

The native file input is notoriously hard to style. Learn the label technique to create beautiful custom upload buttons and drag-drop zones.

The Problem

Native file inputs look different in every browser and are nearly impossible to style directly. The solution is to hide the input and style a label element instead.

Native file input (try styling this!):

Solution: Hidden Input + Styled Label

Live Preview

Drag and Drop Zone

Live Preview

Key Points

  • +Use sr-only or similar to hide the input accessibly
  • +The label's for attribute must match the input's id
  • +Use :focus-within on the wrapper for keyboard focus styling
  • +JavaScript is needed to display the selected file name

Frequently Asked Questions

Why can't I style file inputs directly?

Browser security prevents direct styling of file inputs to protect users. The file name display and browse button are rendered by the browser, not CSS. The workaround is to hide the input and style a label that triggers it.

Is this approach accessible?

Yes, when done correctly. The input remains in the DOM (just visually hidden), so screen readers can access it. The label's for attribute connects it to the input, and keyboard focus works normally.

How do I show the selected file name?

You need JavaScript to display the file name. Listen for the 'change' event on the input, then display input.files[0].name in a span or update the label text.