File Input

Input field for uploading one or more files

Full-width rounded rectangle with dashed border. Inside the rectangle are a large upload icon and some text. Heading text reads "Drag and drop files," followed by a subheader that reads "Up to 10MB per file in JPG, JPEG, PNG, MP4", and underlined text that reads "Browse files".
File upload container that acts as both a drop zone and a file input field

Introduction

File input is an input field for selecting one or more files. It often pairs with file preview cards to implement a complete file upload pattern with visual previews of the files that will be submitted.

Working Example

View a fully styled example in our eBay Skin CSS framework.

Best Practices

File input must have an accessible label, such as "Browse files."

File input should support drag-and-drop, to allow for multiple interaction options. Most browsers now support drag-and-drop for file input fields by default.

It is recommended to include helper text to inform the user about the availability of drag-and-drop and any constraints on file size or type.

Visual Display

By default, browsers display file input fields as a composite of two elements:

  • A file selector button, with text like "Browse..." or "Choose File"

  • Text displaying the selected file name(s), or "No file(s) selected"

To provide a larger, more prominent interaction target, authors may visually obscure these elements in favor of a visual container that includes the field label, helper text, and/or additional visual elements.

  • If the default file selector button is obscured, the container must display a clear call to action. This could be the field's label, e.g. "Browse files."

  • If the default selected file display is obscured, there must be another visual representation of the files to be submitted. File preview cards are one way to accomplish this.

Find implementation details in the Developer Guide.

Interaction Design

Keyboard

File input must be keyboard focusable (unless disabled). Any custom styling must ensure a clear focus state distinct from unfocused state.

When the file input has keyboard focus, pressing ENTERor SPACEBAR must open the operating system's native file browser, where the user can use their operating system's typical file browsing controls to navigate and select file(s).

Screen reader

The file input must announce its label to screen reader users.

The file input must announce its role to screen reader users.

Pointer

Clicking the file input field or its label must open the operating system's native file browser.

It is recommended that file input also support drag-and-drop. The entire file input container should be treated as a drop zone; dragging and dropping files directly onto the file input field's container should select the file(s) for upload.

Developer Guide

HTML gives us a native file input that is keyboard and screenreader accessible.

Base code

At its simplest, the only code you need for file input is a label and an input, including the multiple attribute if the user may upload multiple files:

<label for="documents">Browse files</label>
<input id="documents" type="file" multiple />

This code results in a label followed by the browser's default file input display:

Chrome's default file input display, with a "Choose File" button followed by text that either says "No file(s) chosen" or lists out the names of the selected file(s)

Larger interactive container

What if you want a larger interactive container? Using CSS grids, you can overlap a file input with related visual elements by placing them in the same grid area. This maintains proper semantics while providing a more prominent interaction target and larger drop zone.

File input container with "Drag and drop files" heading, helper text explaining file constraints, and a "Browse files" label
<div class="file-input">
  <div class="file-input__instructions">
   <h4>Drag and drop files</h4>
   <span id="document-reqs">Up to 10MB per file in JPG, JPEG, PNG, MP4.</span>
   <label for="documents">Browse files</label>
  </div>
  <input
    id="documents"
    type="file"
    aria-describedby="document-reqs"
    class="file-input__input"
    multiple
  />
</div>
// Container grid with single template area
.file-input {
    display: grid;
    grid-template-areas: "center";
    grid-template-columns: 1fr;
    grid-template-rows: 1fr;
}

// Instructions and input positioned in same grid area
.file-input__instructions,
.file-input__input {
  grid-area: center;
}

.file-input__instructions {
  // Instructions layered on top of input
  z-index: 1;
  background-color: var(--background-primary);
  border: 1px dashed;
    
  // Any pointer interactions on instructions
  // get passed through to the input below it
  pointer-events: none;
}

View a fully styled example in our eBay Skin CSS framework.

Further Reading

Last updated