<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()">×</span>`;
div.appendChild(img);
gallery.appendChild(div);
};
}Nothing to show yetType HTML, CSS or JavaScript and your page appears here.
Click any element to find its code Esc
Check this code before you run it
It came from a shared link. It runs with fewer permissions, so it cannot open pop-ups, submit forms or start downloads.
0.00s / 0.00s
Nothing has animated yet. Hover, click or type in the preview and each CSS animation, transition or
element.animate() call shows up here as it plays.