<label class='upload !normal'>
<input type='file'>
<span class='button field'>Upload</span>
Pick a file...
</label>
Overview
By default, file upload fields look terribly ugly. The a17t .upload
element is a mostly-headless way to override the default style with ease. It hides the file input, makes button field
s look nice (this is the most common element used with .upload
elements), and ensures that the cursor looks right.
It’s important that you use a <label>
as the parent element (that has the .upload
selector applied). If you don’t, it won’t automatically associate with the <input>
, and your file upload input won’t function.
Considerations
Use with labels — Make sure that the .upload
element is an HTML <label>
. Not only does this have important accessibility consequences, your input won’t work without it.
Tab index — Because the .upload
element hides the actual file <input>
element, it’s critical that you set the tabindex="0"
attribute on the parent <label>
in order retain keyboard interactivity.
Interactivity — You can use JavaScript to update the text associated with the upload element when the user selects a file. Unfortunately, this isn’t the sort of thing that CSS can do automatically.
Variants
File uploads are headless — they don’t have a default style on their own — so you can use them in any number of variants.
Accessibility
Use Aria roles and labels. When building forms, it’s easy to rely on visual guidelines to show relationships between elements. Unfortunately, this doesn’t help those interacting with your site using a screenreader or other assistive technologies. For this reason, it’s important to use ARIA labels and roles wherever possible.
Don't use color to communicate. Instead, use color to support information you communicate through text. When this isn't possible, be sure to use a title
attribute.
Be mindful of contrast. What looks good to you may not be readable for others. Text contrast is a good thing!
Support all navigation modes. Some people will interact with your interface using assitive technologies and/or a keyboard. Build your interface with these different modes in mind (for example, by setting the `tab-index` attribute on all interactive elements that aren't interactive by default).
Examples
Example code
<label class='upload !normal'>
<input type='file'>
<span class='button field'>Upload</span>
Pick a file...
</label>
Example code
<label class='upload !normal'>
<input type='file'>
<span class='button ~neutral !high'>Select a File</span>
<span>screenshot.jpg</span>
</label>
Associated files
Only images are supported right now!
Example code
<p class="label">Associated files</p>
<label class='upload !normal my-2'>
<input type='file' accept="image/*">
<span class='button field'>Choose Photo</span>
<span>screenshot.jpg</span>
</label>
<p class="support">Only images are supported right now!</p>
Customization
This element has no variables.
You can also customize this element by simply overriding any of its CSS attributes, listed
here. Contextual variable defaults (e.g., --color-content
) and global
variables (e.g., --family-primary
) are defined here.