A modern website often needs a file upload system to let users easily upload documents, images or other resources. Instead of relying on a plain file input, you can create an interactive drag & drop file upload form using HTML, CSS and JavaScript.
This design improves the user experience by making the process more intuitive, engaging and user-friendly.
HTML Structure
The HTML is built around a simple form element with a file upload zone. It includes:
<form class="upload-wrapper">
<h2>Upload Files</h2>
<p>Click or drop & drop below to upload the files</p>
<div class="upload-zone">
<div class="icon bi bi-cloud-upload"></div>
<p class="file-name">No File Uploaded</p>
<p class="file-size">0.00 KB</p>
<input type="file" id="input-file" name="file" accept="image/*" required>
</div>
<div class="action-btns">
<button type="reset" id="reset-btn">Cancel</button>
<button type="submit" id="convert-btn">Convert</button>
</div>
</form>
- A title (
<h2>
) and description (<p>
) for clarity. - A drag-and-drop zone with an upload icon, file name and file size.
- A hidden
<input type="file">
field for selecting files manually. - Two buttons: Cancel (reset) and Convert (submit).
This ensures accessibility and keeps the upload form structured and easy to use.
CSS Styling
The CSS creates a modern card-style layout with smooth visual feedback for our File upload form:
@import url(https://fonts.googleapis.com/css2?family=Baloo+Bhai+2:wght@400&display=swap);
@import url(https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css);
body {
display: flex;
min-height: 100vh;
align-items: center;
background: #f1f1f1;
justify-content: center;
font-family: 'Baloo Bhai 2';
}
.upload-wrapper {
display: grid;
width: 500px;
height: 400px;
padding: 20px;
border-radius: 15px;
background-color: white;
grid-template-rows: auto auto 1fr auto;
box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.256);
}
.upload-zone {
width: 100%;
display: grid;
margin: 15px 0;
cursor: pointer;
position: relative;
text-align: center;
border-radius: 10px;
justify-items: center;
align-content: center;
border: 1.6px dashed #00000070;
}
#input-file {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
cursor: pointer;
opacity: 0;
}
.bi-cloud-upload {
line-height: 1;
font-size: 50px;
}
.action-btns {
display: flex;
gap: 20px;
}
button {
flex-grow: 1;
border: none;
padding: 8px;
font-size: 15px;
cursor: pointer;
font-weight: 600;
border-radius: 10px;
letter-spacing: .8px;
font-family: 'Baloo Bhai 2';
background-color: rgb(211, 211, 211);
}
#reset-btn:hover {
background-color: rgb(195, 195, 195);
}
#convert-btn {
background-color: rgb(215, 106, 28);
color: white;
}
#convert-btn:hover {
background-color: rgb(234, 123, 43);
}
.is-dragging {
border: 2px dashed rgb(255, 170, 11);
background-color: rgba(255, 166, 0, 0.163);
}
- Dashed borders in the upload area to signal drag-and-drop functionality.
- Hover and drag states (
.is-dragging
) that highlight the active drop zone. - Responsive card design with shadows and rounded corners.
- Styled buttons with hover effects — a grey cancel button and a bright orange submit button.
The visual style makes the file upload form look professional and user-friendly.
JavaScript Functionality
The JavaScript adds interactivity to the file upload form:
const uploadBox = document.querySelector('.upload-wrapper')
const uploadZone = document.querySelector('.upload-zone');
const resetBtn = document.querySelector('#reset-btn');
const inputFile = document.querySelector('#input-file');
const fileName = document.querySelector('.file-name');
const fileSize = document.querySelector('.file-size');
const handleOnChange = (file) => {
fileName.textContent = file.name;
fileSize.textContent = (file.size / 1024).toFixed(2) + "KB"
}
inputFile.addEventListener("change", (e) => handleOnChange(e.target.files[0]))
uploadBox.addEventListener("submit", (e) => e.preventDefault())
uploadBox.addEventListener("reset", () => {
fileName.textContent = "No File Uploaded";
fileSize.textContent = "0.00 KB"
})
uploadZone.addEventListener('dragenter', () => uploadZone.classList.add('is-dragging'));
uploadZone.addEventListener('dragover', (e) => e.preventDefault());
uploadZone.addEventListener('dragleave', (e) => {
if (!uploadZone.contains(e.relatedTarget)) {
uploadZone.classList.remove('is-dragging');
}
});
uploadZone.addEventListener("drop", (e) => {
e.preventDefault()
uploadZone.classList.remove('is-dragging')
handleOnChange(e.dataTransfer.files[0])
})
- Displays file name and size once a file is selected or dropped.
- Drag & drop support with visual highlighting when dragging over the zone.
- Reset button clears the file name and size.
- Prevents default form submission to allow integration with backend APIs (e.g., file conversion, image processing).
This lightweight script ensures smooth behavior across devices and browsers.
Use Cases
This drag-and-drop file upload form is ideal for:
- Image upload tools (profile picture, gallery uploads).
- File converters (PDF to Word, image compression, etc.).
- Document submissions (resumes, portfolios or reports).
- Custom dashboards where user uploads are required.
Benefits
- Improved UX: Users can either click to upload or drag & drop files.
- Modern UI design with clear visual indicators.
- Lightweight & responsive, built with pure HTML, CSS and JavaScript (no frameworks needed).
- Easy integration with backend APIs for processing uploaded files.
Final Thoughts
This drag-and-drop file upload form is a must-have feature for any modern web application. With minimal code, you can provide users with a sleek, professional and responsive way to upload files. Whether you’re building a portfolio site, online converter or document submission portal, this component fits right in.