File Upload Progress Bar with HTML, CSS & JavaScript

40 DAYS 40 PROJECT CHALLENGE

Day #06

Project Overview

The File Upload Progress Bar is a simple and responsive frontend project built using HTML, CSS, and JavaScript. It allows users to select multiple files and simulate the upload process through an animated progress bar. This project also displays the upload percentage from 0% to 100% and shows an “Upload Complete ✅” message when the progress reaches 100%. After the simulated upload finishes, users can view file names, file sizes, download links, and image previews for uploaded image files.

This project is useful for learning the JavaScript File API, DOM manipulation, progress animations, object URLs, and event handling. The upload process is simulated in the browser and does not send files to a backend server.

Key Features

  • Multiple File Selection: Users can select multiple files through the file input field. The multiple attribute allows the application to handle more than one file at a time.
  • Upload Button: The Upload button starts the simulated upload process. JavaScript first checks whether the user has selected at least one file.
  • Animated Progress Bar: A visual progress bar displays the upload progress. Its width increases gradually from 0% to 100%, creating a smooth animation.
  • Real-Time Percentage Display: The percentage text updates alongside the progress bar. Users can track the simulated progress as it increases.
  • Upload Completion Message: When the progress reaches 100%, the application displays an “Upload Complete” message and shows the selected files.
  • File Information: Each uploaded file displays its name and size in kilobytes. This information is generated using the JavaScript File API.
  • Download Functionality: The application creates a temporary object URL for each file and provides a Download link. Users can click the link to download the selected file.
  • Image Preview: If the selected file is an image, JavaScript dynamically creates an image element and displays a preview below the file information.
  • Input Validation: If users click Upload without selecting a file, the application displays an alert asking them to select at least one file.
  • Clean Interface: The project uses a centered white upload container, a green progress bar, and simple file cards for an easy-to-use interface.

What You'll Learn

  • How to create a file upload interface using HTML.
  • How to select multiple files with the File API.
  • How to access selected files through the files property.
  • How to simulate progress using setInterval().
  • How to update a progress bar dynamically with JavaScript.
  • How to use document.createElement() for dynamic elements.
  • How to generate temporary file URLs using URL.createObjectURL().
  • How to display file names and sizes.
  • How to detect image files using the file MIME type.
  • How to create image previews dynamically.
  • How to add download links for selected files.
  • How to handle file input validation and user feedback.

HTML Code

The HTML structure creates the upload interface inside the .upload-container element. It includes a heading, a file input field, and an Upload button. The file input uses the multiple attribute, allowing users to select several files.

The .progress-container contains the progress bar with the progressBar ID. JavaScript updates this element’s width during the simulated upload. The progressText paragraph displays the current percentage or completion message. and in last, the fileList container displays the selected file details after the upload simulation finishes. The HTML file connects the external CSS and JavaScript files.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Multi File Upload</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>

  <div class="upload-container">
    <h2>Upload Files</h2>

    <input type="file" id="fileInput" multiple>
    <button onclick="uploadFiles()">Upload</button>

    <div class="progress-container">
      <div class="progress-bar" id="progressBar"></div>
    </div>

    <p id="progressText">0%</p>

    <div id="fileList" class="file-list"></div>
  </div>

  <script src="script.js"></script>
</body>
</html>

CSS Code

The CSS code creates a centered upload interface using Flexbox. The body selector sets a dark blue background and uses display: flex, justify-content: center, and align-items: center to position the upload container in the center of the screen. The .upload-container class creates a white card with padding, rounded corners, a fixed width of 400px, and a subtle box shadow. The button uses a green background, white text, rounded corners, and a hover effect that slightly changes its background color.

This .progress-container selector creates the outer progress area with a light gray background, rounded edges, and hidden overflow. Meanwhile, .progress-bar starts with a width of 0% and uses transition: width 0.3s ease to animate progress updates smoothly and the .file-list class adds spacing above the displayed files and aligns the content to the left. Each .file-item receives a light background, padding, rounded corners, and spacing between file entries.

Finally, .file-item img limits image previews to the container’s width, while .download-btn styles the download link with a blue background and white text.

body {
  font-family: Arial, sans-serif;
  background: #042354;
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
}

.upload-container {
  background: white;
  padding: 30px;
  border-radius: 10px;
  width: 400px;
  text-align: center;
  box-shadow: 0 5px 20px rgba(0,0,0,0.08);
}

h2 {
  margin-bottom: 20px;
}

input[type="file"] {
  margin-bottom: 15px;
}

button {
  background: #4CAF50;
  color: white;
  border: none;
  padding: 10px 20px;
  cursor: pointer;
  border-radius: 5px;
  margin-bottom: 20px;
}

button:hover {
  background: #45a049;
}

.progress-container {
  width: 100%;
  background: #eee;
  border-radius: 20px;
  height: 20px;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  width: 0%;
  background: #4CAF50;
  transition: width 0.3s ease;
}

.file-list {
  margin-top: 20px;
  text-align: left;
}

.file-item {
  background: #f9f9f9;
  padding: 10px;
  border-radius: 6px;
  margin-bottom: 10px;
  font-size: 14px;
}

.file-item img {
  max-width: 100%;
  margin-top: 8px;
  border-radius: 6px;
}

.download-btn {
  display: inline-block;
  margin-top: 8px;
  padding: 5px 10px;
  font-size: 12px;
  background: #2196F3;
  color: white;
  text-decoration: none;
  border-radius: 4px;
}

Javascript Code

The JavaScript code manages file selection, progress animation, file information, image previews, and download links. The uploadFiles() function first selects the file input, progress bar, percentage text, and file list using document.getElementById(). It checks whether the user has selected any files through fileInput.files.length. If no file is selected, the function displays an alert and stops execution. Otherwise, the progress starts at zero, and the progress bar and percentage text are reset.

The application uses setInterval() to increase the progress by 5% every 150 milliseconds. The progress bar’s width and percentage text are updated during each interval. When the progress reaches 100%, clearInterval() stops the timer, the completion message appears, and the displayFiles() function is called and the displayFiles() function converts the selected FileList into an array using Array.from() and loops through each file with forEach(). It creates a new file container using document.createElement(), then generates a temporary URL with URL.createObjectURL().

Each file displays its name, size in kilobytes, and a download link. The function checks whether the file is an image using file.type.startsWith("image/"). If the condition is true, it creates an image element, assigns the object URL to its src, and appends the preview to the file container. Finally, each file container is added to the fileList element.

function uploadFiles() {
  const fileInput = document.getElementById("fileInput");
  const progressBar = document.getElementById("progressBar");
  const progressText = document.getElementById("progressText");
  const fileList = document.getElementById("fileList");

  if (!fileInput.files.length) {
    alert("Please select at least one file.");
    return;
  }

  let progress = 0;
  progressBar.style.width = "0%";
  progressText.innerText = "0%";

  const interval = setInterval(() => {
    progress += 5;
    progressBar.style.width = progress + "%";
    progressText.innerText = progress + "%";

    if (progress >= 100) {
      clearInterval(interval);
      progressText.innerText = "Upload Complete ✅";

      displayFiles(fileInput.files);
    }
  }, 150);
}

function displayFiles(files) {
  const fileList = document.getElementById("fileList");

  Array.from(files).forEach(file => {
    const fileItem = document.createElement("div");
    fileItem.classList.add("file-item");

    const fileURL = URL.createObjectURL(file);

    fileItem.innerHTML = `
      <strong>${file.name}</strong><br>
      Size: ${(file.size / 1024).toFixed(2)} KB<br>
      <a href="${fileURL}" download="${file.name}" class="download-btn">Download</a>
    `;

    // If image, show preview
    if (file.type.startsWith("image/")) {
      const img = document.createElement("img");
      img.src = fileURL;
      fileItem.appendChild(img);
    }

    fileList.appendChild(fileItem);
  });
}
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments

Related Projects

Day 3 : E-commerce Product Page

Generates an OTP via alert and verifies it through a popup-based input UI.

Concepts: DOM manipulation, modal UI, random OTP generation, input handling.

Day 4 : Invoice Generator

Creates invoices dynamically with item details and real-time total calculation.

Concepts: DOM manipulation, form handling, calculations, data rendering.

Day 8 : Resume Builder

Interactive resume builder with live preview and editable sections.

Concepts: User input handling, dynamic rendering, state management.