9+ JavaScript Download Button Examples

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&amp;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">&#68;ownload</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&amp;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>&#68;ownload</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&amp;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>&#x44;&#x6F;&#x77;&#x6E;&#x6C;&#x6F;&#x61;&#x64;</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">&bull; #codevember &bull; <a href="https://codepen.io/collection/nxZbMW/" target="_blank">View Collection</a> &bull;<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>