About this snippet

Allow users to upload multiple images at once with this drag and drop zone. It automatically generates thumbnails for every file selected, so your users can review their choices before submitting the form.

Size
3.7 KB
Uses
HTML, CSS, JavaScript
Loads
Nothing external
Views
405
<div class="multi-upload">
  <div class="drop-area" id="dropArea">
    <svg class="upload-icon" viewBox="0 0 24 24" width="48" height="48" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path><polyline points="17 8 12 3 7 8"></polyline><line x1="12" y1="3" x2="12" y2="15"></line></svg>
    <h3>Drag & Drop Images Here</h3>
    <p>or <span class="browse-btn">browse files</span> from your computer</p>
    <input type="file" id="fileElem" multiple accept="image/*" class="file-input">
  </div>
  <div class="gallery" id="gallery"></div>
</div>
.multi-upload {
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
  width: 100%;
  max-width: 600px;
  margin: 0 auto;
}
.drop-area {
  border: 2px dashed #d1d5db;
  border-radius: 16px;
  padding: 40px;
  text-align: center;
  background: #f9fafb;
  cursor: pointer;
  transition: all 0.3s ease;
  position: relative;
}
.drop-area.highlight {
  border-color: #3b82f6;
  background: #eff6ff;
}
.upload-icon {
  color: #9ca3af;
  margin-bottom: 15px;
}
.drop-area h3 {
  margin: 0 0 10px 0;
  color: #1f2937;
}
.drop-area p {
  margin: 0;
  color: #6b7280;
  font-size: 0.95rem;
}
.browse-btn {
  color: #2563eb;
  font-weight: 600;
  text-decoration: underline;
}
.file-input {
  position: absolute;
  width: 100%;
  height: 100%;
  top: 0;
  left: 0;
  opacity: 0;
  cursor: pointer;
}
.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, 1fr));
  gap: 15px;
  margin-top: 20px;
}
.gallery-item {
  position: relative;
  width: 100%;
  height: 100px;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 4px 6px -1px rgba(0,0,0,0.1);
}
.gallery-item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.remove-file {
  position: absolute;
  top: 4px;
  right: 4px;
  background: rgba(0,0,0,0.6);
  color: white;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  cursor: pointer;
}
const dropArea = document.getElementById("dropArea");
const fileElem = document.getElementById("fileElem");
const gallery = document.getElementById("gallery");

// Prevent default drag behaviors
["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => {
  dropArea.addEventListener(eventName, preventDefaults, false);
});

function preventDefaults(e) {
  e.preventDefault();
  e.stopPropagation();
}

// Highlight drop area when item is dragged over it
["dragenter", "dragover"].forEach(eventName => {
  dropArea.addEventListener(eventName, highlight, false);
});

["dragleave", "drop"].forEach(eventName => {
  dropArea.addEventListener(eventName, unhighlight, false);
});

function highlight() {
  dropArea.classList.add("highlight");
}

function unhighlight() {
  dropArea.classList.remove("highlight");
}

// Handle dropped files
dropArea.addEventListener("drop", handleDrop, false);

function handleDrop(e) {
  const dt = e.dataTransfer;
  const files = dt.files;
  handleFiles(files);
}

// Handle selected files via input
fileElem.addEventListener("change", function() {
  handleFiles(this.files);
});

function handleFiles(files) {
  ([...files]).forEach(previewFile);
}

function previewFile(file) {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onloadend = function() {
    const img = document.createElement("img");
    img.src = reader.result;
    
    const div = document.createElement("div");
    div.classList.add("gallery-item");
    div.innerHTML = `<span class="remove-file" onclick="this.parentElement.remove()">&times;</span>`;
    div.appendChild(img);
    gallery.appendChild(div);
  };
}
Esc
↑↓ moveEnter select

Start from a template

Open an .html file, or HTML, CSS, JS, Markdown, Less or TypeScript files. You can also drop them here. Styles and scripts go into their panes.

Share

Source

Keyboard shortcuts

Save