"Download button animation"
Bootstrap 4.1.1 Snippet by koshikojha

<link href="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/css/bootstrap.min.css" rel="stylesheet" id="bootstrap-css"> <script src="//maxcdn.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.min.js"></script> <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script> <!------ Include the above in your HEAD tag ----------> <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>
.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; -webkit-perspective: 500px; 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; -webkit-transform: translateZ(8px); 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 .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; -webkit-transform: translateY(-1px); transform: translateY(-1px); } .dl-button > div .icon div svg.shape { color: var(--color); transition: color .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; -webkit-transform: translateY(0) scale(var(--s)); 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 .4s ease; -webkit-transform: translateZ(8px); transform: translateZ(8px); } .dl-button > div .label > div { display: flex; transition: opacity .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 .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; -webkit-transform: translateY(var(--y)) translateZ(0); transform: translateY(var(--y)) translateZ(0); } .dl-button > div .label > div .counter ul:nth-child(1) { transition: -webkit-transform calc(var(--duration) * .2ms) ease-in-out; transition: transform calc(var(--duration) * .2ms) ease-in-out; transition: transform calc(var(--duration) * .2ms) ease-in-out, -webkit-transform calc(var(--duration) * .2ms) ease-in-out; } .dl-button > div .label > div .counter ul:nth-child(2) { transition: -webkit-transform calc(var(--duration) * .8ms) ease-in-out; transition: transform calc(var(--duration) * .8ms) ease-in-out; transition: transform calc(var(--duration) * .8ms) ease-in-out, -webkit-transform calc(var(--duration) * .8ms) ease-in-out; } .dl-button > div .label > div .counter ul:nth-child(3) { transition: -webkit-transform calc(var(--duration) * .8ms) ease-in-out; transition: transform calc(var(--duration) * .8ms) ease-in-out; transition: transform calc(var(--duration) * .8ms) ease-in-out, -webkit-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; -webkit-transform-origin: 50% 100%; transform-origin: 50% 100%; -webkit-transform: scaleY(var(--s)); transform: scaleY(var(--s)); transition: -webkit-transform .4s ease; transition: transform .4s ease; transition: transform .4s ease, -webkit-transform .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; -webkit-transform-origin: 0 50%; transform-origin: 0 50%; -webkit-transform: scaleX(var(--s)); transform: scaleX(var(--s)); } .dl-button > div .progress:before { opacity: .35; } .dl-button > div .progress:after { --s: 0; transition: -webkit-transform calc(var(--duration) * .9ms) ease-in-out; transition: transform calc(var(--duration) * .9ms) ease-in-out; transition: transform calc(var(--duration) * .9ms) ease-in-out, -webkit-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: .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: .4s; } .dl-button.active > div .progress:after { --s: 1; transition-delay: .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% { -webkit-transform: translateY(100%); transform: translateY(100%); opacity: 1; } 39% { -webkit-transform: translateY(100%); transform: translateY(100%); opacity: 0; } 40% { -webkit-transform: translateY(-100%); transform: translateY(-100%); opacity: 0; } 41% { -webkit-transform: translateY(-100%); transform: translateY(-100%); opacity: 1; } 100% { -webkit-transform: translateY(-1px); transform: translateY(-1px); opacity: 1; } } @keyframes arrow { 38% { -webkit-transform: translateY(100%); transform: translateY(100%); opacity: 1; } 39% { -webkit-transform: translateY(100%); transform: translateY(100%); opacity: 0; } 40% { -webkit-transform: translateY(-100%); transform: translateY(-100%); opacity: 0; } 41% { -webkit-transform: translateY(-100%); transform: translateY(-100%); opacity: 1; } 100% { -webkit-transform: translateY(-1px); transform: translateY(-1px); opacity: 1; } } @-webkit-keyframes span { 25% { -webkit-transform: translateY(2px) scale(var(--s)); transform: translateY(2px) scale(var(--s)); } 55% { -webkit-transform: translateY(2px) scale(var(--s)); transform: translateY(2px) scale(var(--s)); } 80%, 100% { -webkit-transform: translateY(0) scale(var(--s)); transform: translateY(0) scale(var(--s)); } } @keyframes span { 25% { -webkit-transform: translateY(2px) scale(var(--s)); transform: translateY(2px) scale(var(--s)); } 55% { -webkit-transform: translateY(2px) scale(var(--s)); transform: translateY(2px) scale(var(--s)); } 80%, 100% { -webkit-transform: translateY(0) scale(var(--s)); transform: translateY(0) scale(var(--s)); } } @-webkit-keyframes motion { 20%, 70% { -webkit-filter: blur(0.4px); filter: blur(0.4px); } } @keyframes motion { 20%, 70% { -webkit-filter: blur(0.4px); filter: blur(0.4px); } } @-webkit-keyframes button { 0% { -webkit-transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); } 10% { -webkit-transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg); transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg); box-shadow: 0 4px 8px var(--shadow-dark); } 20% { -webkit-transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg); transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg); box-shadow: 4px 12px 20px var(--shadow-dark); } 85% { -webkit-transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg); transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg); box-shadow: -4px 12px 20px var(--shadow-dark); } 95% { -webkit-transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg); transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg); box-shadow: 0 8px 24px var(--shadow-dark); } 100% { -webkit-transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); } } @keyframes button { 0% { -webkit-transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); } 10% { -webkit-transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg); transform: translateX(0) translateZ(0) scale(0.96) rotateY(0deg); box-shadow: 0 4px 8px var(--shadow-dark); } 20% { -webkit-transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg); transform: translateX(-16px) translateZ(32px) scale(1) rotateY(-16deg); box-shadow: 4px 12px 20px var(--shadow-dark); } 85% { -webkit-transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg); transform: translateX(16px) translateZ(32px) scale(1) rotateY(16deg); box-shadow: -4px 12px 20px var(--shadow-dark); } 95% { -webkit-transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg); transform: translateX(0) translateZ(0) scale(1.12) rotateY(0deg); box-shadow: 0 8px 24px var(--shadow-dark); } 100% { -webkit-transform: translateX(0) translateZ(0) scale(1) rotateY(0deg); 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%; -webkit-transform: translateX(-50%); transform: translateX(-50%); color: var(--grey-dark); font-size: 14px; line-height: 16px; text-decoration: none; opacity: 0; visibility: hidden; transition: opacity .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; }
$('.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(); } }); }

Related: See More


Questions / Comments: