100 Days of CSS: Day 15

February 21, 2025

Upload: Yes, you can actually drag and drop a file in there. But don't worry, the upload process is faked.'

Unsplash ↗

Project Structure

The project consists of 3 main files:

HTML Structure

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

<div class="frame">
  <div class="center">
		<div class="bar"></div>
		<div class="title">Drop file to upload</div>
		<div class="dropzone">
			<div class="content">
				<img src="https://100dayscss.com/codepen/upload.svg" class="upload">
				<span class="filename"></span>
				<input type="file" class="input">
			</div>
		</div>
		<img src="https://100dayscss.com/codepen/syncing.svg" class="syncing">
		<img src="https://100dayscss.com/codepen/checkmark.svg" class="done">
		<div class="upload-btn">Upload file</div>
  </div>
</div>

CSS Styling

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

@import url(https://fonts.googleapis.com/css?family=Open+Sans:700,400);

// use only the available space inside the 400x400 frame
.frame {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 400px;
  height: 400px;
  margin-top: -200px;
  margin-left: -200px;
  border-radius: 2px;
	box-shadow: 1px 2px 10px 0 rgba(0,0,0,0.3);
	overflow: hidden;
  background: #3A92AF;
  color: #fff;
	font-family: 'Open Sans', Helvetica, sans-serif;
	background: linear-gradient(to top right, #3A92AF 0%, #5CA05A 100%); 
	-webkit-font-smoothing: antialiased;
	-moz-osx-font-smoothing: grayscale;
}

.center {
  position: absolute;
	width: 300px;
	height: 260px;
  top: 70px;
  left: 50px;
	background: #fff;
	box-shadow: 8px 10px 15px 0 rgba(0,0,0,0.2);
	border-radius: 3px;
}

.title {
	font-size: 16px;
	color: #676767;
	line-height: 50px;
	height: 50px;
	border-bottom: 1px solid #D8D8D8;
	text-align: center;
}

.dropzone {
	position:absolute;
	z-index:1;
	box-sizing: border-box;
	display:table;
	table-layout:fixed;
	width: 100px;
	height: 80px;
	top: 86px;
	left: 100px;
	border: 1px dashed #A4A4A4;
	border-radius: 3px;
	text-align: center;
	overflow: hidden;
	
	&.is-dragover {
		border-color: #666;
		background: #eee;
	}
	
	.content {
		display: table-cell;
		vertical-align: middle;
	}
	
	.filename {
		display: block;
		color: #676767;
		font-size:14px;
		line-hieght: 18px;
	}
	
	.input {
		position:absolute;
		top:0;
		left:0;
		right:0;
		bottom:0;
		opacity:0;
	}
}

.upload-btn {
	position:absolute;
	width: 140px;
	height: 40px;
	left: 80px;
	bottom: 24px;
	background: #6ECE3B;
	border-radius: 2px;
	text-align: center;
	line-height: 40px;
	font-size: 14px;
	box-shadow: 0 2px 0 0 #498C25;
	cursor: pointer;
	transition: all .2s ease-in-out;
	
	&:hover {
		box-shadow: 0 2px 0 0 #498C25, 0 2px 10px 0 #6ECE3B;
	}
	
	
	
}

.bar {
	position: absolute;
	z-index: 1;
	width: 300px;
	height: 3px;
	top: 49px;
	left:0;
	background: #6ECE38;
	transition: all 3s ease-out;
	transform: scaleX(0);
	transform-origin: 0 0;
	
	&.active {
		transform: scaleX(1) translate3s(0,0,0);
	}
	
}

.syncing {
	position: absolute;
	top: 109px;
	left: 134px;
	opacity: 0;
	
	&.active {
		animation: syncing 3.2s ease-in-out;
	}
}

.done {
	position: absolute;
	top: 112px;
	left: 132px;
	opacity: 0;
	
	&.active {
		animation: done .5s ease-in 3.2s;
		animation-fill-mode: both;
	}
}


@keyframes syncing {
	0% {
		transform: rotate(0deg);
	}
	10% {
		opacity: 1;
	}
	90% {
		opacity: 1;	
	}
	100% {
		transform: rotate(360deg);
		opacity: 0;
	}
}

@keyframes done {
	from {
		opacity: 0;
	}
	to {
		opacity: 1;
	}
}

Javascript

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam posuere erat at mi sagittis ultricies. Aenean cursus libero vitae odio congue volutpat.

var droppedFiles = false;
var fileName = '';
var $dropzone = $('.dropzone');
var $button = $('.upload-btn');
var uploading = false;
var $syncing = $('.syncing');
var $done = $('.done');
var $bar = $('.bar');
var timeOut;

$dropzone.on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
	e.preventDefault();
	e.stopPropagation();
})
	.on('dragover dragenter', function() {
	$dropzone.addClass('is-dragover');
})
	.on('dragleave dragend drop', function() {
	$dropzone.removeClass('is-dragover');
})
	.on('drop', function(e) {
	droppedFiles = e.originalEvent.dataTransfer.files;
	fileName = droppedFiles[0]['name'];
	$('.filename').html(fileName);
	$('.dropzone .upload').hide();
});

$button.bind('click', function() {
	startUpload();
});

$("input:file").change(function (){
	fileName = $(this)[0].files[0].name;
	$('.filename').html(fileName);
	$('.dropzone .upload').hide();
});

function startUpload() {
	if (!uploading && fileName != '' ) {
		uploading = true;
		$button.html('Uploading...');
		$dropzone.fadeOut();
		$syncing.addClass('active');
		$done.addClass('active');
		$bar.addClass('active');
		timeoutID = window.setTimeout(showDone, 3200);
	}
}

function showDone() {
	$button.html('Done');
}

Reflection