This post contains a total of 9+ Hand-Picked JavaScript Download Button Examples with Source Code. All the Download Buttons are made using JavaScript & Styled using CSS.
You can use the source code of these examples for educational purpose with credits to the original owner.
Related Posts
Click a Code to Copy it.
1. By Aaron Iker
Made by Aaron Iker. JavaScript download button with progress bar animation and restart button. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:400,500,700&display=swap'>
<style>
.dl-button {
--duration: 4000;
--success: #16BF78;
--grey-light: #99A3BA;
--grey: #6C7486;
--grey-dark: #3F4656;
--light: #CDD9ED;
--shadow: rgba(18, 22, 33, .6);
--shadow-dark: rgba(18, 22, 33, .85);
display: block;
text-decoration: none;
perspective: 500px;
}
.dl-button > div {
position: relative;
background: #fff;
border-radius: 5px;
overflow: hidden;
display: flex;
padding: 16px 24px;
box-shadow: 0 4px 12px var(--shadow);
}
.dl-button > div .icon {
--color: var(--grey);
margin-right: 12px;
position: relative;
transform: translateZ(8px);
}
.dl-button > div .icon div {
overflow: hidden;
position: relative;
width: 20px;
height: 22px;
}
.dl-button > div .icon div:before, .dl-button > div .icon div:after {
content: "";
position: absolute;
width: 2px;
height: 2px;
top: 2px;
transition: opacity 0.3s ease;
}
.dl-button > div .icon div:before {
left: 6px;
background-image: radial-gradient(circle at 0 100%, var(--color) 2px, #fff 0px);
}
.dl-button > div .icon div:after {
right: 6px;
background-image: radial-gradient(circle at 100% 100%, var(--color) 2px, #fff 0px);
}
.dl-button > div .icon div svg {
width: 20px;
height: 18px;
display: block;
margin-top: 2px;
position: relative;
z-index: 1;
}
.dl-button > div .icon div svg.arrow {
color: #fff;
position: absolute;
left: 0;
top: 0;
z-index: 2;
transform: translateY(-1px);
}
.dl-button > div .icon div svg.shape {
color: var(--color);
transition: color 0.4s ease;
}
.dl-button > div .icon span {
--s: 1;
position: absolute;
left: 1px;
right: 1px;
bottom: 2px;
background: var(--color);
height: 6px;
border-radius: 50%;
display: block;
transform: translateY(0) scale(var(--s));
}
.dl-button > div .label {
--color: var(--grey-dark);
line-height: 22px;
font-size: 16px;
font-weight: 500;
color: var(--color);
position: relative;
transition: color 0.4s ease;
transform: translateZ(8px);
}
.dl-button > div .label > div {
display: flex;
transition: opacity 0.25s ease;
}
.dl-button > div .label > div:not(.show) {
position: absolute;
left: 0;
top: 0;
opacity: 0;
}
.dl-button > div .label > div.hide {
opacity: 0;
}
.dl-button > div .label > div .counter {
overflow: hidden;
display: flex;
height: 18px;
line-height: 18px;
margin: 2px 0;
position: relative;
transition: opacity 0.3s ease;
}
.dl-button > div .label > div .counter:before, .dl-button > div .label > div .counter:after {
content: "";
display: block;
position: absolute;
left: 0;
right: 0;
height: 3px;
z-index: 1;
}
.dl-button > div .label > div .counter:before {
top: 0;
background: linear-gradient(to bottom, white 0%, rgba(255, 255, 255, 0) 100%);
}
.dl-button > div .label > div .counter:after {
bottom: 0;
background: linear-gradient(to top, white 0%, rgba(255, 255, 255, 0) 100%);
}
.dl-button > div .label > div .counter span {
display: inline-block;
margin: 0 4px 0 2px;
}
.dl-button > div .label > div .counter ul {
--y: 0;
margin: 0;
padding: 0;
list-style: none;
width: 10px;
height: 18px;
-webkit-backface-visibility: hidden;
transform: translateY(var(--y)) translateZ(0);
}
.dl-button > div .label > div .counter ul:nth-child(1) {
transition: transform calc(var(--duration) * .2ms) ease-in-out;
}
.dl-button > div .label > div .counter ul:nth-child(2) {
transition: transform calc(var(--duration) * .8ms) ease-in-out;
}
.dl-button > div .label > div .counter ul:nth-child(3) {
transition: transform calc(var(--duration) * .8ms) ease-in-out;
}
.dl-button > div .label > div .counter ul li {
width: 10px;
height: 18px;
}
.dl-button > div .label > div .counter.hide {
opacity: 0;
}
.dl-button > div .progress {
--s: 0;
position: absolute;
left: 0;
right: 0;
bottom: 0;
height: 3px;
transform-origin: 50% 100%;
transform: scaleY(var(--s));
transition: transform 0.4s ease;
}
.dl-button > div .progress:before, .dl-button > div .progress:after {
--s: 1;
content: "";
background: var(--success);
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
transform-origin: 0 50%;
transform: scaleX(var(--s));
}
.dl-button > div .progress:before {
opacity: 0.35;
}
.dl-button > div .progress:after {
--s: 0;
transition: transform calc(var(--duration) * .9ms) ease-in-out;
}
.dl-button.active > div {
-webkit-animation: button calc(var(--duration) * 1ms) linear forwards;
animation: button calc(var(--duration) * 1ms) linear forwards;
}
.dl-button.active > div .icon div:before, .dl-button.active > div .icon div:after {
opacity: 0;
transition-delay: 0.4s;
}
.dl-button.active > div .icon svg.arrow {
-webkit-animation: arrow calc(var(--duration) * .18ms) linear 4 calc(var(--duration) * .2ms);
animation: arrow calc(var(--duration) * .18ms) linear 4 calc(var(--duration) * .2ms);
}
.dl-button.active > div .icon span {
-webkit-animation: span calc(var(--duration) * .18ms) linear 4 calc(var(--duration) * .2ms);
animation: span calc(var(--duration) * .18ms) linear 4 calc(var(--duration) * .2ms);
}
.dl-button.active > div .label > div .counter ul:nth-child(1) {
--y: -18px;
transition-delay: calc(var(--duration) * .72ms);
}
.dl-button.active > div .label > div .counter ul:nth-child(2) {
--y: -180px;
transition-delay: calc(var(--duration) * .09ms);
-webkit-animation: motion calc(var(--duration) * .5ms) linear forwards calc(var(--duration) * .19ms);
animation: motion calc(var(--duration) * .5ms) linear forwards calc(var(--duration) * .19ms);
}
.dl-button.active > div .label > div .counter ul:nth-child(3) {
--y: -540px;
transition-delay: calc(var(--duration) * .075ms);
-webkit-animation: motion calc(var(--duration) * .8ms) linear forwards calc(var(--duration) * .075ms);
animation: motion calc(var(--duration) * .8ms) linear forwards calc(var(--duration) * .075ms);
}
.dl-button.active > div .progress {
--s: 1;
transition-delay: 0.4s;
}
.dl-button.active > div .progress:after {
--s: 1;
transition-delay: 0.4s;
}
.dl-button.done > div .icon {
--color: var(--success);
}
.dl-button.done .label {
--color: var(--success);
}
.dl-button.done .label .counter {
width: 0;
}
@-webkit-keyframes arrow {
38% {
transform: translateY(100%);
opacity: 1;
}
39% {
transform: translateY(100%);
opacity: 0;
}
40% {
transform: translateY(-100%);
opacity: 0;
}
41% {
transform: translateY(-100%);
opacity: 1;
}
100% {
transform: translateY(-1px);
opacity: 1;
}
}
@keyframes arrow {
38% {
transform: translateY(100%);
opacity: 1;
}
39% {
transform: translateY(100%);
opacity: 0;
}
40% {
transform: translateY(-100%);
opacity: 0;
}
41% {
transform: translateY(-100%);
opacity: 1;
}
100% {
transform: translateY(-1px);
opacity: 1;
}
}
@-webkit-keyframes span {
25% {
transform: translateY(2px) scale(var(--s));
}
55% {
transform: translateY(2px) scale(var(--s));
}
80%, 100% {
transform: translateY(0) scale(var(--s));
}
}
@keyframes span {
25% {
transform: translateY(2px) scale(var(--s));
}
55% {
transform: translateY(2px) scale(var(--s));
}
80%, 100% {
transform: translateY(0) scale(var(--s));
}
}
@-webkit-keyframes motion {
20%, 70% {
filter: blur(0.4px);
}
}
@keyframes motion {
20%, 70% {
filter: blur(0.4px);
}
}
@-webkit-keyframes button {
0% {
transform: translateX(0) translateZ(0) scale(1) rotateY(0deg);
}
10% {
transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg);
box-shadow: 0 4px 8px var(--shadow-dark);
}
20% {
transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg);
box-shadow: 4px 12px 20px var(--shadow-dark);
}
85% {
transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg);
box-shadow: -4px 12px 20px var(--shadow-dark);
}
95% {
transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg);
box-shadow: 0 8px 24px var(--shadow-dark);
}
100% {
transform: translateX(0) translateZ(0) scale(1) rotateY(0deg);
}
}
@keyframes button {
0% {
transform: translateX(0) translateZ(0) scale(1) rotateY(0deg);
}
10% {
transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg);
box-shadow: 0 4px 8px var(--shadow-dark);
}
20% {
transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg);
box-shadow: 4px 12px 20px var(--shadow-dark);
}
85% {
transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg);
box-shadow: -4px 12px 20px var(--shadow-dark);
}
95% {
transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg);
box-shadow: 0 8px 24px var(--shadow-dark);
}
100% {
transform: translateX(0) translateZ(0) scale(1) rotateY(0deg);
}
}
.dl-button.done + .restart {
opacity: 1;
visibility: visible;
}
.restart {
--grey-dark: #3F4656;
position: absolute;
bottom: 20%;
left: 50%;
transform: translateX(-50%);
color: var(--grey-dark);
font-size: 14px;
line-height: 16px;
text-decoration: none;
opacity: 0;
visibility: hidden;
transition: opacity 0.4s ease;
}
.restart svg {
width: 16px;
height: 16px;
margin-right: 4px;
display: inline-block;
vertical-align: top;
}
html {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: inherit;
}
*:before, *:after {
box-sizing: inherit;
}
body {
min-height: 100vh;
font-family: Roboto, Arial;
display: flex;
justify-content: center;
align-items: center;
background: #242836;
padding: 20px;
}
body .dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
}
body .dribbble img {
display: block;
height: 28px;
}
</style>
</head>
<body>
<a class="dl-button" href="">
<div>
<div class="icon">
<div>
<svg class="arrow" viewBox="0 0 20 18" fill="currentColor">
<polygon points="8 0 12 0 12 9 15 9 10 14 5 9 8 9"></polygon>
</svg>
<svg class="shape" viewBox="0 0 20 18" fill="currentColor">
<path d="M4.82668561,0 L15.1733144,0 C16.0590479,0 16.8392841,0.582583769 17.0909106,1.43182334 L19.7391982,10.369794 C19.9108349,10.9490677 19.9490212,11.5596963 19.8508905,12.1558403 L19.1646343,16.3248465 C19.0055906,17.2910371 18.1703851,18 17.191192,18 L2.80880804,18 C1.82961488,18 0.994409401,17.2910371 0.835365676,16.3248465 L0.149109507,12.1558403 C0.0509788145,11.5596963 0.0891651114,10.9490677 0.260801785,10.369794 L2.90908938,1.43182334 C3.16071592,0.582583769 3.94095214,0 4.82668561,0 Z"></path>
</svg>
</div><span></span>
</div>
<div class="label">
<div class="show default">Download</div>
<div class="state">
<div class="counter">
<ul>
<li></li>
<li>1</li>
</ul>
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
</ul>
<ul>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
<li>0</li>
</ul><span>%</span>
</div><span>Done</span>
</div>
</div>
<div class="progress"></div>
</div></a><a class="restart" href="">
<svg viewBox="0 0 16 16" fill="currentColor">
<path d="M4.5,4.5c1.9-1.9,5.1-1.9,7,0c0.7,0.7,1.2,1.7,1.4,2.7l2-0.3C14.7,5.4,14,4.1,13,3.1c-2.7-2.7-7.1-2.7-9.9,0 L0.9,0.9L0.2,7.3l6.4-0.7L4.5,4.5z"></path>
<path d="M15.8,8.7L9.4,9.4l2.1,2.1c-1.9,1.9-5.1,1.9-7,0c-0.7-0.7-1.2-1.7-1.4-2.7l-2,0.3 C1.3,10.6,2,11.9,3,12.9c1.4,1.4,3.1,2,4.9,2c1.8,0,3.6-0.7,4.9-2l2.2,2.2L15.8,8.7z"></path>
</svg>Restart</a><a class="dribbble" href="https://dribbble.com/shots/6766237-Download-Button-Animation" target="_blank"><img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg"/></a>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js'></script>
<script>
$('.dl-button').on('click', e => {
let btn = $(e.currentTarget),
label = btn.find('.label'),
counter = label.find('.counter');
if (!btn.hasClass('active') && !btn.hasClass('done')) {
btn.addClass('active');
setLabel(label, label.find('.default'), label.find('.state'));
setTimeout(() => {
counter.addClass('hide');
counter.animate({
width: 0 },
400, function () {
label.width(label.find('.state > span').width());
counter.removeAttr('style');
});
btn.removeClass('active').addClass('done');
}, getComputedStyle(btn[0]).getPropertyValue('--duration'));
}
return false;
});
$('.restart').on('click', e => {
let btn = $('.dl-button'),
label = btn.find('.label'),
counter = label.find('.counter');
setLabel(label, label.find('.state'), label.find('.default'), function () {
counter.removeClass('hide');
btn.removeClass('done');
});
return false;
});
function setLabel(div, oldD, newD, callback) {
oldD.addClass('hide');
div.animate({
width: newD.outerWidth() },
200, function () {
oldD.removeClass('show hide');
newD.addClass('show');
div.removeAttr('style');
if (typeof callback === 'function') {
callback();
}
});
}
</script>
</body>
</html>
2. By Aaron Iker
Another JavaScript download button by Aaron Iker. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>CodePen - Bounce download button</title>
<link rel='stylesheet' href='https://fonts.googleapis.com/css?family=Roboto:400,500,700&display=swap'>
<style>
.button {
--background: #2B3044;
--text: #fff;
--icon: #fff;
--icon-success: #16BF78;
display: flex;
outline: none;
border: 0;
padding: 0 22px 0 16px;
min-width: 147px;
overflow: hidden;
cursor: pointer;
border-radius: 9px;
background: var(--background);
transition: transform 0.2s;
}
.button:active {
transform: scale(0.95);
}
.button ul {
margin: 0;
padding: 13px 0;
list-style: none;
text-align: center;
position: relative;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
font-size: 16px;
font-weight: 500;
line-height: 25px;
color: var(--text);
}
.button ul li:not(:first-child) {
top: var(--t, 13px);
left: 0;
position: absolute;
}
.button ul li:nth-child(2) {
--t: 64px;
}
.button ul li:nth-child(3) {
--t: 115px;
}
.button .icon {
width: 24px;
height: 24px;
position: relative;
display: inline-block;
vertical-align: top;
margin: 14px 10px 0 0;
transform: translateY(calc(var(--y, 0) * 1px));
}
.button .icon svg {
width: var(--w, 14px);
height: var(--h, 15px);
display: block;
fill: none;
stroke: var(--s, var(--icon));
stroke-width: var(--sw, 2);
stroke-linejoin: round;
stroke-linecap: round;
}
.button .icon > svg,
.button .icon div {
left: var(--l, 7px);
top: var(--t, 2px);
position: absolute;
}
.button .icon > svg {
transform: translateY(calc(var(--y, 0) * 1px));
}
.button .icon > svg polyline,
.button .icon > svg line {
stroke-dasharray: var(--a, 12px);
stroke-dashoffset: var(--o, 0);
stroke: var(--s, var(--icon));
transition: stroke-dashoffset var(--d, 0.15s), stroke 0.4s;
}
.button .icon > svg polyline {
--d: .25s;
--a: 17px;
--o: 5.5px;
}
.button .icon div {
--w: 24px;
--h: 24px;
--l: 0;
--t: 8px;
--sw: 1.5;
}
.button.loading ul {
-webkit-animation: text 1750ms linear forwards 100ms;
animation: text 1750ms linear forwards 100ms;
}
.button.loading.complete .icon svg line {
--o: 12px;
}
.button.loading.complete .icon svg polyline {
--o: 0;
--s: var(--icon-success);
}
@-webkit-keyframes text {
18%, 82% {
transform: translateY(-100%);
}
100% {
transform: translateY(-200%);
}
}
@keyframes text {
18%, 82% {
transform: translateY(-100%);
}
100% {
transform: translateY(-200%);
}
}
html {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: inherit;
}
*:before, *:after {
box-sizing: inherit;
}
body {
min-height: 100vh;
display: flex;
font-family: "Roboto", Arial;
justify-content: center;
align-items: center;
flex-direction: column;
background: #F6F8FF;
}
body .dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
}
body .dribbble img {
display: block;
height: 28px;
}
body .twitter {
position: fixed;
display: block;
right: 64px;
bottom: 14px;
}
body .twitter svg {
width: 32px;
height: 32px;
fill: #1da1f2;
}
</style>
</head>
<body>
<button class="button">
<div class="icon">
<svg viewBox="0 0 14 15">
<line x1="5" y1="13" x2="5" y2="1"></line>
<polyline id="tick" points="1 9.5 5 13.5 13 5.5"></polyline>
<polyline id="normal" points="1 9.5 5 13.5 9 9.5"></polyline>
</svg>
<div>
<svg viewBox="0 0 24 24"></svg>
</div>
</div>
<ul>
<li>Download</li>
<li>Waiting</li>
<li>Open file</li>
</ul>
</button>
<a class="dribbble" href="https://dribbble.com/shots/9143098-Download-button" target="_blank"><img src="https://cdn.dribbble.com/assets/dribbble-ball-mark-2bd45f09c2fb58dbbfb44766d5d1d07c5a12972d602ef8b32204d28fa3dda554.svg" alt=""></a>
<a class="twitter" target="_blank" href="https://twitter.com/aaroniker_me"><svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72"><path d="M67.812 16.141a26.246 26.246 0 0 1-7.519 2.06 13.134 13.134 0 0 0 5.756-7.244 26.127 26.127 0 0 1-8.313 3.176A13.075 13.075 0 0 0 48.182 10c-7.229 0-13.092 5.861-13.092 13.093 0 1.026.118 2.021.338 2.981-10.885-.548-20.528-5.757-26.987-13.679a13.048 13.048 0 0 0-1.771 6.581c0 4.542 2.312 8.551 5.824 10.898a13.048 13.048 0 0 1-5.93-1.638c-.002.055-.002.11-.002.162 0 6.345 4.513 11.638 10.504 12.84a13.177 13.177 0 0 1-3.449.457c-.846 0-1.667-.078-2.465-.231 1.667 5.2 6.499 8.986 12.23 9.09a26.276 26.276 0 0 1-16.26 5.606A26.21 26.21 0 0 1 4 55.976a37.036 37.036 0 0 0 20.067 5.882c24.083 0 37.251-19.949 37.251-37.249 0-.566-.014-1.134-.039-1.694a26.597 26.597 0 0 0 6.533-6.774z"></path></svg></a>
<script src='https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js'></script>
<script>
const $ = (s, o = document) => o.querySelector(s);
const $$ = (s, o = document) => o.querySelectorAll(s);
$$('.button').forEach(button => {
let icon = $('.icon', button),
arrow = $('.icon > svg', button),
line = $('.icon div svg', button),
svgPath = new Proxy({
y: null },
{
set(target, key, value) {
target[key] = value;
if (target.y !== null) {
line.innerHTML = getPath(target.y, .25, null);
}
return true;
},
get(target, key) {
return target[key];
} });
svgPath.y = 12;
button.addEventListener('click', e => {
if (!button.classList.contains('loading')) {
button.classList.add('loading');
gsap.timeline({
repeat: 2 }).
to(svgPath, {
y: 17,
duration: .17,
delay: .03 }).
to(svgPath, {
y: 12,
duration: .3,
ease: Elastic.easeOut.config(1, .35) });
gsap.timeline({
repeat: 2,
repeatDelay: .1,
onComplete() {
gsap.to(arrow, {
'--y': -17.5,
duration: .4 });
setTimeout(() => button.classList.add('complete'), 200);
} }).
to(arrow, {
'--y': 9,
duration: .2 }).
to(arrow, {
'--y': -9,
duration: .2 });
gsap.timeline().to(icon, {
y: 4,
duration: .2 }).
to(icon, {
y: 8,
duration: .2,
delay: .2 }).
to(icon, {
y: 12,
duration: .2,
delay: .2 }).
to(icon, {
y: 18,
duration: .2,
delay: .2 });
}
e.preventDefault();
});
});
function getPoint(point, i, a, smoothing) {
let cp = (current, previous, next, reverse) => {
let p = previous || current,
n = next || current,
o = {
length: Math.sqrt(Math.pow(n[0] - p[0], 2) + Math.pow(n[1] - p[1], 2)),
angle: Math.atan2(n[1] - p[1], n[0] - p[0]) },
angle = o.angle + (reverse ? Math.PI : 0),
length = o.length * smoothing;
return [current[0] + Math.cos(angle) * length, current[1] + Math.sin(angle) * length];
},
cps = cp(a[i - 1], a[i - 2], point, false),
cpe = cp(point, a[i - 1], a[i + 1], true);
return `C ${cps[0]},${cps[1]} ${cpe[0]},${cpe[1]} ${point[0]},${point[1]}`;
}
function getPath(update, smoothing, pointsNew) {
let points = pointsNew ? pointsNew : [
[2, 12],
[12, update],
[22, 12]],
d = points.reduce((acc, point, i, a) => i === 0 ? `M ${point[0]},${point[1]}` : `${acc} ${getPoint(point, i, a, smoothing)}`, '');
return `<path d="${d}" />`;
}
</script>
</body>
</html>
3. By Rune Sejer Hoffmann
Made by Rune Sejer Hoffmann. Download button with progress animation and bouncing ball animation. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<style>
@import url(https://fonts.googleapis.com/css?family=Nunito:400,700,300);
body {
font-family: "Nunito", sans-serif;
background: #373e46;
}
#loading_line {
width: 0px;
height: 5px;
background: blue;
}
.buttonContainer {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
text-align: center;
cursor: pointer;
}
.buttonContainer .complete {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
margin: auto;
transform: scale(1.9);
color: #f9f9f9;
transition: all 0.3s ease;
opacity: 0;
}
.buttonContainer .complete.fadein {
opacity: 1;
transform: scale(1.5);
}
.buttonContainer #counter {
color: #e91d62;
font-size: 19px;
left: 0;
right: 0;
bottom: 20px;
margin: auto;
display: none;
position: absolute;
}
.buttonContainer .ball {
position: absolute;
left: 0;
right: 0;
top: -26px;
margin: auto;
width: 40px;
height: 40px;
border-radius: 40px;
background-color: #e91d62;
box-shadow: inset 1px 1px 1px 0px rgba(255, 255, 255, 0.54);
display: none;
}
.buttonContainer:before {
content: "Download";
display: block;
text-transform: uppercase;
color: #e91d62;
font-weight: 700;
font-size: 13px;
transform: translateY(38px);
transition: all 0.2s ease;
}
.buttonContainer.active {
pointer-events: none;
}
.buttonContainer.active:before {
opacity: 0;
}
.buttonContainer.active .ball {
-webkit-animation: jump 2s cubic-bezier(0.16, 0.15, 1, 0.49) infinite;
animation: jump 2s cubic-bezier(0.16, 0.15, 1, 0.49) infinite;
}
.buttonContainer.active #button {
stroke-dashoffset: 290;
width: 300px;
stroke-width: 9;
-webkit-animation: struk 2s cubic-bezier(0.16, 0.15, 1, 0.49) infinite;
animation: struk 2s cubic-bezier(0.16, 0.15, 1, 0.49) infinite;
}
.buttonContainer #button {
stroke-dasharray: 411;
stroke-dashoffset: 0;
marker-start: 30;
transform-origin: 50% 50%;
transition: all 0.4s cubic-bezier(0.18, 0.89, 0.32, 1.28);
}
@-webkit-keyframes jump {
0% {
transform: translateY(0%);
}
10% {
transform: translateY(-180%);
}
18% {
width: 40px;
height: 40px;
}
20% {
transform: translateY(10%);
width: 48px;
height: 32px;
}
22% {
width: 40px;
height: 40px;
}
30% {
transform: translateY(-90%);
}
38% {
width: 40px;
height: 40px;
}
40% {
transform: translateY(5%);
width: 44px;
height: 36px;
}
42% {
width: 40px;
height: 40px;
}
49% {
transform: translateY(-40%);
}
57% {
transform: translateY(0%);
}
65% {
transform: translateY(-10%);
}
70% {
transform: translateY(0%);
}
}
@keyframes jump {
0% {
transform: translateY(0%);
}
10% {
transform: translateY(-180%);
}
18% {
width: 40px;
height: 40px;
}
20% {
transform: translateY(10%);
width: 48px;
height: 32px;
}
22% {
width: 40px;
height: 40px;
}
30% {
transform: translateY(-90%);
}
38% {
width: 40px;
height: 40px;
}
40% {
transform: translateY(5%);
width: 44px;
height: 36px;
}
42% {
width: 40px;
height: 40px;
}
49% {
transform: translateY(-40%);
}
57% {
transform: translateY(0%);
}
65% {
transform: translateY(-10%);
}
70% {
transform: translateY(0%);
}
}
@-webkit-keyframes struk {
18% {
transform: translateY(0%);
}
20% {
transform: translateY(10%);
}
22% {
transform: translateY(0%);
}
38% {
transform: translateY(0%);
}
40% {
transform: translateY(5%);
}
42% {
transform: translateY(0%);
}
}
@keyframes struk {
18% {
transform: translateY(0%);
}
20% {
transform: translateY(10%);
}
22% {
transform: translateY(0%);
}
38% {
transform: translateY(0%);
}
40% {
transform: translateY(5%);
}
42% {
transform: translateY(0%);
}
}
</style>
</head>
<body>
<div class="buttonContainer">
<div class="complete">Download complete</div>
<div class="ball"></div>
<svg width="182" height="61" xmlns="http://www.w3.org/2000/svg">
<path id="button" d="m31.048188,4.720621l120.048623,0l0,0c15.726711,0 28.475699,11.640603 28.475699,26.000007c0,14.359399 -12.748994,25.999997 -28.475699,25.999997l-120.048623,0l0,0c-15.726693,0 -28.475699,-11.640598 -28.475699,-25.999997c0,-14.359409 12.749006,-26.000007 28.475699,-26.000007z" stroke-width="4" stroke="#e91d62" fill="none"/>
</svg>
<div id="counter">0</div>
</div>
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script>
$('.buttonContainer').click(function () {
if ($('.buttonContainer').hasClass('active')) {
$(this).removeClass('active');
$('.complete').removeClass('fadein');
$('#counter').fadeOut(100);
$('.ball').fadeOut(100);
count().stop;
} else {
$(this).addClass('active');
$('#counter').fadeIn(200);
$('.ball').fadeIn(200);
count();
}
});
//Loading
function count() {
$({ countNum: $('#counter').text() }).animate({ countNum: 100 }, {
duration: 5000,
easing: 'linear',
step: function () {
$('#counter').text(Math.floor(this.countNum) + '%');
},
complete: function () {
$('#counter').fadeOut(200);
$('.complete').addClass('fadein');
$('.ball').fadeOut(200);
$('#button').fadeOut(100);
setTimeout(function () {
$('.buttonContainer').removeClass('active');
$('.complete').removeClass('fadein');
$('#button').fadeIn(200);
}, 1000);
} });
}
</script>
</body>
</html>
4. By Ana Tudor
Made by Ana Tudor. JavaScript download button with border progress animation. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<style>
html {
background: #3a3a3a;
}
body {
text-align: center;
}
button {
box-sizing: border-box;
margin-top: calc(50vh - 2em);
border: solid 0.25em transparent;
padding: 1px;
width: 10em;
border-radius: 5px;
box-shadow: 1px 1px 1px -1px rgba(85, 85, 85, 0.75), 1px 1px 2px -1px rgba(85, 85, 85, 0.75);
background: radial-gradient(rgba(90, 90, 90, 0.65) 25%, rgba(90, 90, 90, 0) 75%) 0 0/100% 0.125em no-repeat padding-box, repeating-linear-gradient(45deg, rgba(12, 12, 12, 0.35), transparent 1px, transparent 3px, rgba(12, 12, 12, 0.35) 4px) content-box, repeating-linear-gradient(-45deg, rgba(12, 12, 12, 0.35), transparent 1px, transparent 3px, rgba(12, 12, 12, 0.35) 4px) content-box, linear-gradient(#2a2a2a, #050505) content-box, linear-gradient(#323232, #232323) padding-box, linear-gradient(#3bc8ef, rgba(59, 200, 239, 0.1)) 0/0 100% no-repeat border-box, repeating-linear-gradient(45deg, rgba(34, 34, 34, 0.25), transparent 1px, transparent 3px, rgba(34, 34, 34, 0.25) 4px) border-box, repeating-linear-gradient(-45deg, rgba(34, 34, 34, 0.25), transparent 1px, transparent 3px, rgba(34, 34, 34, 0.25) 4px) border-box, linear-gradient(#3bc8ef, #3bc8ef) 0/0 100% no-repeat border-box, linear-gradient(#151515, #2e2e2e) border-box;
color: #fff;
font: 500 1.25em/2.4 verdana, sans-serif;
text-transform: uppercase;
cursor: pointer;
}
button:not(.loading):active {
transform: scale(0.98);
}
button:focus {
outline: none;
box-shadow: 1px 1px 1px -1px rgba(59, 200, 239, 0.5);
}
.loading {
position: relative;
color: transparent;
cursor: auto;
}
.loading:after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
color: #3bc8ef;
content: attr(data-perc);
}
</style>
</head>
<body>
<button>download</button>
<script>
var rID = null;
var load = function (el, s, t) {
var perc,k = 2;
if (t % k === 0) {
perc = t / k;
el.dataset.perc = perc + '%';
el.style.backgroundSize =
s.replace(/0px/g, el.dataset.perc);
if (perc === 100) {
cancelAnimationFrame(rID);
rID = null;
return;
}
}
rID = requestAnimationFrame(
load.bind(this, el, s, ++t));
};
document.querySelector('button').
addEventListener('click', function () {
var s;
if (!rID) {
this.classList.toggle('loading');
s = getComputedStyle(this).backgroundSize;
if (this.classList.contains('loading'))
load(this, s, 0);else
{
this.dataset.perc =
this.style.backgroundSize = '';
}
}
}, false);
</script>
</body>
</html>
5. By Andrei
Made by Andrei. Download button with pause option. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<style>
@import url("https://fonts.googleapis.com/css?family=Montserrat:100,300,400,500,700,900");
@import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css");
body {
background-color: #333;
width: 100%;
font-family: "Montserrat", sans-serif;
font-size: 24px;
overflow-x: hidden;
text-align: center;
}
h1 {
text-transform: uppercase;
text-align: center;
color: #fff;
}
h5 {
text-transform: uppercase;
text-align: center;
color: #fff;
font-weight: 100;
}
.download-btn {
cursor: pointer;
display: inline-block;
}
.download {
fill: #028EFF;
stroke: #028EFF;
stroke-dashoffset: 10%;
}
.download--animate {
-webkit-animation: circle-animate-1 2s forwards, circle-animate-2 0.5s 4s forwards;
animation: circle-animate-1 2s forwards, circle-animate-2 0.5s 4s forwards;
}
.download-btn {
position: relative;
height: 140px;
width: 140px;
}
.bar {
stroke: #028EFF;
}
.bar--animate {
-webkit-animation-name: bar-animate;
animation-name: bar-animate;
-webkit-animation-duration: 3s;
animation-duration: 3s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.btn--icon {
transition: 0.3s;
position: absolute;
font-size: 54px;
left: 47px;
top: 40px;
}
.btn__arrow {
color: #fff;
opacity: 1;
}
.btn__arrow--animate {
-webkit-animation-name: arrow-animate;
animation-name: arrow-animate;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.btn__stop {
color: #028EFF;
opacity: 0;
}
.btn__stop--animate {
-webkit-animation-name: stop-animate;
animation-name: stop-animate;
-webkit-animation-duration: 3s;
animation-duration: 3s;
-webkit-animation-delay: 1s;
animation-delay: 1s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.btn__done {
color: #fff;
opacity: 0;
}
.btn__done--animate {
-webkit-animation-name: done-animate;
animation-name: done-animate;
-webkit-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-delay: 4s;
animation-delay: 4s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
@-webkit-keyframes arrow-animate {
0% {
opacity: 1;
transform: rotate(0deg);
}
100% {
opacity: 0;
transform: rotate(180deg);
}
}
@keyframes arrow-animate {
0% {
opacity: 1;
transform: rotate(0deg);
}
100% {
opacity: 0;
transform: rotate(180deg);
}
}
@-webkit-keyframes stop-animate {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
85% {
opacity: 1;
transform: rotate(0deg);
}
100% {
opacity: 0;
transform: rotate(180deg);
}
}
@keyframes stop-animate {
0% {
opacity: 0;
}
10% {
opacity: 1;
}
85% {
opacity: 1;
transform: rotate(0deg);
}
100% {
opacity: 0;
transform: rotate(180deg);
}
}
@-webkit-keyframes done-animate {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes done-animate {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes circle-animate-1 {
0% {
fill: #028EFF;
stroke: #028EFF;
}
100% {
fill: #fff;
stroke: #D1EAFE;
}
}
@keyframes circle-animate-1 {
0% {
fill: #028EFF;
stroke: #028EFF;
}
100% {
fill: #fff;
stroke: #D1EAFE;
}
}
@-webkit-keyframes circle-animate-2 {
0% {
fill: #fff;
stroke: #D1EAFE;
}
100% {
fill: #3bc27a;
stroke: #3bc27a;
}
}
@keyframes circle-animate-2 {
0% {
fill: #fff;
stroke: #D1EAFE;
}
100% {
fill: #3bc27a;
stroke: #3bc27a;
}
}
@-webkit-keyframes bar-animate {
0% {
opacity: 0;
transform: rotate(0deg);
stroke-dashoffset: 565px;
}
5% {
opacity: 1;
}
25% {
stroke-dashoffset: 450px;
}
50% {
stroke-dashoffset: 350px;
}
75% {
stroke-dashoffset: 250px;
}
99% {
stroke-dashoffset: 20px;
stroke: #028EFF;
}
100% {
stroke-dashoffset: 5px;
stroke: #3bc27a;
}
}
@keyframes bar-animate {
0% {
opacity: 0;
transform: rotate(0deg);
stroke-dashoffset: 565px;
}
5% {
opacity: 1;
}
25% {
stroke-dashoffset: 450px;
}
50% {
stroke-dashoffset: 350px;
}
75% {
stroke-dashoffset: 250px;
}
99% {
stroke-dashoffset: 20px;
stroke: #028EFF;
}
100% {
stroke-dashoffset: 5px;
stroke: #3bc27a;
}
}
</style>
</head>
<body>
<header>
<h1>css3+js download button</h1>
<h5>click on the button to see the magic</h5></header>
<div class="download-btn">
<div class="btn__circle"> <svg width="140" height="140">
<circle r="60" cx="70" cy="70"
class='download' stroke-width="10" />
</circle>
<circle class="bar" stroke-width="10" r="60" cx="70" cy="70" fill="transparent" stroke ='red' stroke-dasharray="565.48" stroke-dashoffset="565.48"></circle>
</svg>
</div>
<div class="btn__arrow btn--icon"><i class="fa fa-arrow-down" aria-hidden="true"></i></div>
<div class="btn__stop btn--icon"><i class="fa fa-pause" aria-hidden="true"></i></div>
<div class="btn__done btn--icon"><i class="fa fa-check" aria-hidden="true"></i></div>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js'></script>
<script>
//animation trigger on click
$(".download-btn").click(function () {
$(".download").toggleClass("download--animate");
$(".bar").toggleClass("bar--animate");
$(".btn__arrow").toggleClass("btn__arrow--animate");
$(".btn__stop").toggleClass("btn__stop--animate");
$(".btn__done").toggleClass("btn__done--animate");
});
</script>
</body>
</html>
6. By Jon Kantner
Made by Jon Kantner. Morphing Icon Download Button. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<link rel='stylesheet' href='https://fonts.googleapis.com/css2?family=Hind&display=swap'>
<style>
* {
border: 0;
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--dur: 3s;
--arrowA: polygon(33% 0%,67% 0%,67% 60%,100% 60%,50% 100%,0% 60%,33% 60%);
--arrowB: polygon(0% 37.5%,100% 37.5%,100% 62.5%,100% 62.5%,50% 62.5%,0% 62.5%,0% 62.5%);
font-size: calc(20px + (40 - 20)*(100vw - 320px)/(2560 - 320));
}
body, button {
display: flex;
font: 1em/1.5 Hind, sans-serif;
}
body {
background: #e3e4e8;
height: 100vh;
overflow: hidden;
}
button {
background: #255ff4;
border-radius: 0.2em;
color: #fff;
cursor: pointer;
display: flex;
margin: auto;
padding: 0.5em 1em;
position: relative;
transition: background 0.15s linear;
width: 10.5em;
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
-webkit-tap-highlight-color: transparent;
}
button:focus {
outline: transparent;
}
button::-moz-focus-inner {
border: 0;
}
button:not(:disabled):focus, button:not(:disabled):hover {
background: #0b46da;
}
button:not(:disabled):active {
transform: translateY(1px);
}
button:disabled {
cursor: not-allowed;
}
button span, button:before, button:after {
display: inline-block;
pointer-events: none;
}
button:before, button:after {
border-radius: 0.25em;
opacity: 0;
top: 1em;
left: 1.3em;
height: 0.5em;
transform-origin: 0.25em 50%;
z-index: 2;
}
button:before {
transform: rotate(-180deg);
width: 0.8em;
}
button:after {
width: 1.2em;
}
button:before, button:after, .dl-icon:before, .dl-icon:after {
content: "";
display: block;
position: absolute;
}
button:before, button:after, .dl-icon:before {
background: currentColor;
}
button span + span {
margin: auto;
}
.dl-icon {
margin-right: 0.5em;
position: relative;
width: 1.5em;
height: 1.5em;
}
.dl-icon:before {
clip-path: var(--arrowA);
-webkit-clip-path: var(--arrowA);
top: 0;
left: calc(50% - 0.55em);
transform-origin: 50% 100%;
width: 1.1em;
height: 1em;
z-index: 1;
}
.dl-icon:after {
background-image: linear-gradient(#0b46da,#0b46da);
background-position: -1.5em 0;
background-size: 100% 100%;
background-repeat: no-repeat;
box-shadow:
0.25em 0 0 inset,
-0.25em 0 0 inset,
0 -0.25em 0 inset;
bottom: 0;
width: 100%;
height: 0.5em;
}
.dl-working:before {
animation: checkOutA var(--dur) linear forwards;
}
.dl-working:after {
animation: checkOutB var(--dur) linear forwards;
}
.dl-working .dl-icon {
animation: impact var(--dur) linear forwards;
}
.dl-working .dl-icon:before {
animation: arrowToBar var(--dur) linear forwards;
}
.dl-working .dl-icon:after {
animation: trayToBar var(--dur) linear forwards;
}
/* Animation */
@keyframes impact {
from, 15% {
transform: translateY(0);
}
17.5% {
transform: translateY(0.25em);
}
20%, to {
transform: translateY(0);
}
}
@keyframes arrowToBar {
from {
clip-path: var(--arrowA);
-webkit-clip-path: var(--arrowA);
}
10% {
clip-path: var(--arrowB);
-webkit-clip-path: var(--arrowB);
transform: translateY(0);
}
15% {
clip-path: var(--arrowB);
-webkit-clip-path: var(--arrowB);
transform: translateY(0.625em);
}
30% {
clip-path: var(--arrowB);
-webkit-clip-path: var(--arrowB);
opacity: 1;
transform: translateY(0.125em);
}
35%, to {
clip-path: var(--arrowB);
-webkit-clip-path: var(--arrowB);
opacity: 0;
transform: translateY(0.125em);
}
}
@keyframes trayToBar {
from, 15% {
background-color: transparent;
border-radius: 0;
box-shadow:
0.25em 0 0 inset,
-0.25em 0 0 inset,
0 -0.25em 0 inset;
transform: translateY(0);
}
15.1% {
background-color: currentColor;
border-radius: 0;
box-shadow:
0 0 0 inset,
0 0 0 inset,
0 0 0 0.1em inset;
transform: translateY(0);
}
30% {
background-color: currentColor;
background-position: -1.5em 0;
border-radius: 0.25em;
box-shadow:
0 0 0 inset,
0 0 0 inset,
0 0 0 0.1em inset;
transform: translateY(-0.5em);
}
90% {
background-color: currentColor;
background-position: 0 0;
border-radius: 0.25em;
box-shadow:
0 0 0 inset,
0 0 0 inset,
0 0 0 0.1em inset;
opacity: 1;
transform: translateY(-0.5em);
}
90.1%, to {
background-color: currentColor;
background-position: 0 0;
border-radius: 0.25em;
box-shadow:
0 0 0 inset,
0 0 0 inset,
0 0 0 0.1em inset;
opacity: 0;
transform: translateY(-0.5em);
}
}
@keyframes checkOutA {
from, 90% {
opacity: 0;
transform: translate(0,0) rotate(-180deg);
}
90.1% {
opacity: 1;
width: 0.8em;
transform: translate(0,0) rotate(-180deg);
}
92.5% {
opacity: 1;
width: 1em;
transform: translate(0,0.5em) rotate(-120deg);
}
95%, to {
opacity: 1;
width: 1em;
transform: translate(0,0.375em) rotate(-135deg);
}
}
@keyframes checkOutB {
from, 90% {
opacity: 0;
transform: translate(0,0) rotate(0);
}
90.1% {
opacity: 1;
width: 1.2em;
transform: translate(0,0) rotate(0);
}
92.5% {
opacity: 1;
width: 1.6em;
transform: translate(0,0.5em) rotate(-60deg);
}
95%, to {
opacity: 1;
width: 1.6em;
transform: translate(0,0.375em) rotate(-45deg);
}
}
/* Dark mode */
@media (prefers-color-scheme: dark) {
body {
background: #2e3138;
}
}
</style>
</head>
<body>
<button type="button" data-dl>
<span class="dl-icon"></span><span>Download</span>
</button>
<script>
document.addEventListener("DOMContentLoaded", function () {
this.addEventListener("click", e => {
let tar = e.target;
if (tar.hasAttribute("data-dl")) {
let dlClass = "dl-working";
if (!tar.classList.contains(dlClass)) {
let lastSpan = tar.querySelector("span:last-child"),
lastSpanText = lastSpan.textContent,
timeout = getMSFromProperty("--dur", ":root");
tar.classList.add(dlClass);
lastSpan.textContent = "Downloading…";
tar.disabled = true;
setTimeout(() => {
lastSpan.textContent = "Completed!";
}, timeout * 0.9);
setTimeout(() => {
tar.classList.remove(dlClass);
lastSpan.textContent = lastSpanText;
tar.disabled = false;
}, timeout + 1e3);
}
}
});
});
function getMSFromProperty(property, selector) {
let cs = window.getComputedStyle(document.querySelector(selector)),
transDur = cs.getPropertyValue(property),
msLabelPos = transDur.indexOf("ms"),
sLabelPos = transDur.indexOf("s");
if (msLabelPos > -1)
return transDur.substr(0, msLabelPos);else
if (sLabelPos > -1)
return transDur.substr(0, sLabelPos) * 1e3;
}
</script>
</body>
</html>
7. By Andreas Storm
Made by Andreas Storm. iOS Safari download button made using Js. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<style>
body {
min-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #4e295b;
}
* {
box-sizing: border-box;
}
.btn {
position: relative;
display: inline-block;
width: 48px;
height: 48px;
border-radius: 24px;
}
.btn svg {
fill: none;
width: 20px;
height: 26px;
margin: 11px 0 0 14px;
transform: translate3d(0, 0, 0);
}
.btn svg path {
stroke: #fdd7d2;
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
transition: stroke 0.3s ease;
}
.btn .circle {
position: absolute;
display: block;
top: 0;
left: 0;
height: 48px;
width: 48px;
border-radius: 24px;
border: 3px solid #fdd7d2;
transition: border 0.3s ease;
}
.btn .progress {
position: absolute;
display: block;
bottom: -10px;
left: 0;
height: 3px;
width: 48px;
border-radius: 3px;
background: rgba(253, 215, 210, 0.2);
opacity: 0;
pointer-events: none;
overflow: hidden;
}
.btn .progress:after {
content: "";
display: block;
width: 100%;
height: 3px;
border-radius: 2px;
background: #ff9b8b;
transform-origin: left;
transform: scaleX(0);
transition: transform 2s linear;
}
.btn .progress.active {
opacity: 1;
}
.btn .progress.active::after {
transform: scaleX(1);
}
.btn:hover .circle {
border-color: #ff9b8b;
}
.btn:hover svg path {
stroke: #ff9b8b;
}
.btn:active svg {
transform: translateY(2px);
}
.btn.pending .circle {
border-color: #ff9b8b;
animation: animC 0.6s ease-out;
animation-delay: 2.35s;
}
.btn.pending svg {
animation: animS 0.6s ease-in;
animation-delay: 2.15s;
}
.btn.pending svg path {
stroke: #ff9b8b;
}
@keyframes animS {
5% {
transform: scale(0.9);
}
50% {
transform: translateY(12px);
}
80% {
transform: translateY(-4px);
}
}
@keyframes animC {
50% {
transform: translateY(6px);
}
80% {
transform: translateY(-4px);
}
}
</style>
</head>
<body>
<!--iOS Safari Download Button--><a class="btn" href="#"><span class="circle"></span>
<svg width="20" height="26" viewbox="0 0 20 26">
<path d="M1.5 16.5L10 24.5L18.5 16.5"></path>
<path d="M10 1.5V24"></path>
</svg><span class="progress"></span></a>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
<script>
(function() {
$('.btn').click(function() {
$('.btn').addClass('pending');
$('.progress').addClass('active');
setTimeout((function() {
return $('.progress').removeClass('active');
}), 2300);
return setTimeout((function() {
return $('.btn').removeClass('pending');
}), 3600);
});
}).call(this);
</script>
</body>
</html>
8. By James Fleeting
Made by James Fleeting. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css">
<style>
.container {
flex: 0 0 auto;
width: 70px;
height: 150px;
}
@media screen and (max-height: 255px) {.container {
margin: 25px auto
}
}
.button {
display: inline-block;
padding: 12px 12px 10px;
border: 0;
border-radius: 3px;
background: #bf4d28;
text-decoration: none;
transition: all 1.2s ease-in-out;
}
.button i::after {
content: "\f019";
font-size: 40px;
color: #fff;
}
.button:hover {
-webkit-animation: pulse 0.2s 2 both;
animation: pulse 0.2s 2 both;
}
.button.loading i {
-webkit-animation: loading 2s infinite linear;
animation: loading 2s infinite linear;
}
.button.loading i::after {
content: "\f1ce";
}
.button.success {
border-radius: 50%;
background: #80bca3;
}
.button.success i::after {
content: "\f00c";
color: transparent;
-webkit-animation: change-icon 1s 0.6s linear both;
animation: change-icon 1s 0.6s linear both;
}
@-webkit-keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
@keyframes loading {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(359deg);
}
}
@-webkit-keyframes change-icon {
0% {
color: transparent;
}
100% {
color: #fff;
}
}
@keyframes change-icon {
0% {
color: transparent;
}
100% {
color: #fff;
}
}
@-webkit-keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.05, 1.05, 1.05);
}
to {
transform: scale3d(1, 1, 1);
}
}
@keyframes pulse {
from {
transform: scale3d(1, 1, 1);
}
50% {
transform: scale3d(1.05, 1.05, 1.05);
}
to {
transform: scale3d(1, 1, 1);
}
}
html, body {
height: 100%;
}
@media screen and (max-height: 255px) {
html, body {
height: auto
}
}
body {
display: flex;
flex-direction: column;
flex-shrink: 0;
justify-content: center;
align-items: center;
background: radial-gradient(ellipse at center, #343436 0%,#1d1f20 100%);
}
@media screen and (max-height: 255px) {
body {
display: block
}
}
.view-collection {
flex: 0 0 auto;
margin: 10px 0 0;
color: #fff;
text-align: center;
font-size: 15px;
font-family: 'Montserrat', sans-serif;
line-height: 1.6;
}
@media screen and (max-height: 255px) {
.view-collection {
margin: 25px auto
}
}
.view-collection span {
font-size: 13px;
}
.view-collection .love {
color: #cc0000;
}
.view-collection a {
color: #bf4d28;
text-decoration: none;
transition: all 0.7s;
}
.view-collection a:hover, .view-collection a:focus {
color: #80bca3;
}
</style>
</head>
<body>
<div class="container">
<a href="" class="button"><i class="fa"></i></a>
</div>
<p class="view-collection">• #codevember • <a href="https://codepen.io/collection/nxZbMW/" target="_blank">View Collection</a> •<br />
<span>Handcrafted with <span class="love">♥</span> from Austin, TX by <a href="https://twitter.com/fleetingftw">James Fleeting</a></span></p>
<script src='https://use.fontawesome.com/97152d9c6b.js'></script>
<script>
let downloadButton = document.querySelector('.button');
if (downloadButton) {
downloadButton.addEventListener('click', function (event) {
event.preventDefault();
/* Start loading process. */
downloadButton.classList.add('loading');
/* Set delay before switching from loading to success. */
window.setTimeout(function () {
downloadButton.classList.remove('loading');
downloadButton.classList.add('success');
}, 3000);
/* Reset animation. */
window.setTimeout(function () {
downloadButton.classList.remove('success');
}, 8000);
});
};
</script>
</body>
</html>
9. By Michael Dobekidis
Made by Milan Raring. Cool Download button animation. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<link href='https://fonts.googleapis.com/css?family=Ubuntu+Condensed' rel='stylesheet' type='text/css'>
<style>
body{
position:fixed;
margin:0px;
width:100%;
background: #f7f7f7; /* Old browsers */
background: -moz-linear-gradient(top, #f7f7f7 0%, #fcfcfc 100%); /* FF3.6+ */
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f7f7f7), color-stop(100%,#fcfcfc)); /* Chrome,Safari4+ */
background: -webkit-linear-gradient(top, #f7f7f7 0%,#fcfcfc 100%); /* Chrome10+,Safari5.1+ */
background: -o-linear-gradient(top, #f7f7f7 0%,#fcfcfc 100%); /* Opera 11.10+ */
background: -ms-linear-gradient(top, #f7f7f7 0%,#fcfcfc 100%); /* IE10+ */
background: linear-gradient(to bottom, #f7f7f7 0%,#fcfcfc 100%); /* W3C */
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f7f7f7', endColorstr='#fcfcfc',GradientType=0 ); /* IE6-9 */
}
span{
padding:0px !important;
margin:0px !important;
margin-right:0px !important;
font-family: 'Ubuntu Condensed', sans-serif;
font-size:30px;
color:#01A2F3;
float:left;
}
#container{
width:150px;
height:50px;
border:2px solid #01A2F3;
border-radius:7px;
padding:5px;
padding-left:30px;
text-align:center;
margin:0 auto;
top:100px;
margin-top:100px;
position:relative;
}
#loaderText{
width:100%;
text-align:center;
vertical-align:middle;
margin:0 auto;
height:100%;
position:absolute;
top:12px;
left:50%;
margin-left:-30%;
cursor:pointer;
}
#loaderText2{
width:100%;
text-align:center;
vertical-align:middle;
margin:0 auto;
height:100%;
position:absolute;
top:12px;
left:50%;
margin-left:-38%;
z-index:90;
display:none;
}
#loaderText2>span{
/* color:#ffffff !important; */
/*visibility:hidden;*/
background: url("http://i221.photobucket.com/albums/dd22/djmid71/Untitled-1_zpsb46204f7.png");
background-position:-500px;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-repeat:no-repeat;
}
#loader{
height:60px;
background: #01a2f3; /* Old browsers */
position:absolute;
width:0%;
left:0px;
top:0px;
border-radius-left-top:7px;
z-index:90;
}
#finalText{
visibility:hidden;
opacity:0;
color:#fff;
width:100%;
height:100%;
text-align:center;
font-size:30px;
z-index:99;
position:absolute;
margin-left:-30px;
top:10px;
font-family:'Ubuntu Condensed', sans-serif;
}
</style>
</head>
<body>
<div id="container">
<div id="loader"></div>
<div id="loaderText">
<span>D</span>
<span>o</span>
<span>w</span>
<span>n</span>
<span>l</span>
<span>o</span>
<span>a</span>
<span>d</span>
</div>
<div id="loaderText2">
<span>D</span>
<span>o</span>
<span>w</span>
<span>n</span>
<span>l</span>
<span>o</span>
<span>a</span>
<span>d</span>
<span>i</span>
<span>n</span>
<span>g</span>
</div>
<div id="finalText">
Done!
</div>
</div>
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/1.10.3/TweenMax.min.js'></script>
<script>
$(document).ready(function () {
var perc;
$("#loaderText").on('click', function () {
TweenMax.to("#loader", 7, { width: '100%', ease: Power0.easeOut, onUpdate: function () {
var mainWidth = $("#container").width() + 30;
perc = $("#loader").width() / mainWidth * 100;
console.log(Math.floor(perc), $("#container").width());
checkPercent(Math.floor(perc));
}, onStart: function () {
$("#loaderText").css({ 'visibility': 'hidden' });
$("#loaderText2").css({ 'visibility': 'visible', 'display': 'block' });
} });
});
});
function checkPercent(perc) {
perc = String(perc).replace("px", "");
if (perc == 12) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(0);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 22) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(1);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 32) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(2);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 40) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(3);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 47) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(4);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 51) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(5);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 61) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(6);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 66) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(7);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 74) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(8);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 77) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(9);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 85) {
console.log(perc);
//var obj2Go = $("#loaderText>span").get(0);
// $(obj2Go).css({'visibility':'hidden'});
var obj2Show = $("#loaderText2>span").get(10);
TweenMax.to($(obj2Show), 1, { 'background-position': '-480px 0%' });
} else
if (perc == 100) {
TweenMax.to("#loaderText2", 1, { autoAlpha: 0 });
TweenMax.to("#finalText", 1.2, { autoAlpha: 1 });
}
}
</script>
</body>
</html>
10. By katmai7
Made by katmai7. Source
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title></title>
<link href="//netdna.bootstrapcdn.com/font-awesome/3.0/css/font-awesome.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<style>
html {
height: 100%;
}
body {
height: 100%;
background: #C1D1DA;
background: radial-gradient(ellipse at center, #343435 0%, #171717 100%);
}
.wrap {
margin: 100px auto;
width: 180px;
}
.btn {
position: relative;
z-index: 1;
float: left;
margin-right: 30px;
width: 60px;
height: 60px;
border: none;
border-radius: 50%;
background: radial-gradient(ellipse at center, #eec472 10%, #9e5c10 100%) 0 -3px;
box-shadow: inset 0 1px 3px 0 rgba(249, 231, 97, 0.7), inset 0 -6px 20px -1px rgba(165, 98, 18, 0.8), 0 2px 6px 0 rgba(0, 0, 0, 0.7);
color: #DCAC40;
color: #CA9A33;
text-align: center;
text-shadow: 0 1px 0 #E7B15A;
font-size: 25px;
line-height: 60px;
cursor: pointer;
transition: box-shadow 0.3s ease, color 0.3s ease;
user-select: none;
}
.btn:active,
.btn.active {
outline: 0;
box-shadow: inset 0 1px 3px 0 rgba(249, 231, 97, 0), inset 0 -6px 20px 7px rgba(165, 98, 18, 0.8), 0 2px 6px 0 rgba(0, 0, 0, 0), inset 0 7px 8px 0 rgba(0, 0, 0, 0.6);
color: #C09331;
text-shadow: 0 1px 0 #DDA956;
}
.btn:after {
position: absolute;
top: -7px;
left: -7px;
z-index: -1;
display: block;
width: 74px;
height: 74px;
border-radius: 50%;
background: rgba(255, 255, 255, 0.03);
box-shadow: inset 0 10px 10px -4px rgba(0, 0, 0, 0.7);
content: "";
}
</style>
</head>
<body>
<div class="wrap">
<div class="btn"><i class="icon-cloud-download"></i></div>
<div class="btn active"><i class="icon-cloud-download"></i>
</div>
</div>
<script src='//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script>
$('.btn.active').bind('click', function () {
$(this).toggleClass('active');
});
</script>
</body>
</html>