Custom styled input type file upload button with pure CSS
In this guide I’ll show you how to create a stylish and user friendly file upload button with pure CSS and HTML.
Markup
To upload files you’ll need to use the input
tag with type="file"
attribute. Additionally you can specify which file types you’re allowing to upload via accept
attribute.
HTML:
<input type="file" accept="image/*">
This markup produces a button with a Choose file title followed by a text which indicates the file name when selected. By default it is No file chosen.
Result:
Input with type file default look differs on different browsers:




Styling
The upload file widget structure consists of a block that displays a button and a file name. A user can click anywhere inside the block or drag a file from the desktop and it will open up the upload window.
Styling the upload file block
If you apply styles for the input[type=file]
selector it will set them for the whole widget block, that is the button and text.
CSS:
input[type=file] {
width: 350px;
max-width: 100%;
color: #444;
padding: 5px;
background: #fff;
border-radius: 10px;
border: 1px solid #555;
}
The result already looks much better as it indicates the zone where user is able to click or drag the file.
Result:
Styling the upload file button
By default, the Choose file button has a plain user-agent style. To style the button with CSS you should use the ::file-selector-button
pseudo-element to select it. It is supported in all modern browsers.
CSS:
input[type=file]::file-selector-button {
margin-right: 20px;
border: none;
background: #084cdf;
padding: 10px 20px;
border-radius: 10px;
color: #fff;
cursor: pointer;
transition: background .2s ease-in-out;
}
input[type=file]::file-selector-button:hover {
background: #0d45a5;
}
Result
Styling the the click/drop zone
If you wich to go a bit further, you can create a large zone where user can click and drag files. This large zone will make it easier for people to use the widget, as it don’t require to be that precise when dragging a file, especially on smaller screens.
To implement a large drop zone, you’ll need to wrap your file upload input
into a label
tag and specify a description text that will let users know how to use the widget.
HTML
<label for="images" class="drop-container">
<span class="drop-title">Drop files here</span>
or
<input type="file" id="images" accept="image/*" required>
</label>
For the layout, we need to set display
to flex
with flex related properties for positioning. The height
and padding
properties for proportion. And finally add some fancy styles like border and hover effects to highlight the file upload zone and you’re ready to go.
CSS:
.drop-container {
position: relative;
display: flex;
gap: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
height: 200px;
padding: 20px;
border-radius: 10px;
border: 2px dashed #555;
color: #444;
cursor: pointer;
transition: background .2s ease-in-out, border .2s ease-in-out;
}
.drop-container:hover {
background: #eee;
border-color: #111;
}
.drop-container:hover .drop-title {
color: #222;
}
.drop-title {
color: #444;
font-size: 20px;
font-weight: bold;
text-align: center;
transition: color .2s ease-in-out;
}
Result:
Demo
See the full example on CodePen:
See the Pen Untitled by Nikita Hlopov (@nikitahl) on CodePen.