<button class="button-hold">
<div>
<svg class="progress" viewBox="0 0 32 32">
<circle r="8" cx="16" cy="16" />
</svg>
<svg class="tick" viewBox="0 0 24 24">
<polyline points="18,7 11,16 6,12" />
</svg>
</div>
<ul>
<li>Publish</li>
<li>Sure ?</li>
<li>Public</li>
</ul>
</button>
<!-- twitter / dribbble -->
<a class="dribbble" href="https://dribbble.com/shots/8716260-Hold-to-confirm" target="_blank"><img src="https://dribbble.com/assets/logo-small-2x-9fe74d2ad7b25fba0f50168523c15fda4c35534f9ea0b1011179275383035439.png" 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>
.button-hold {
--color: #F6F8FF;
--background: #1A1E32;
--icon: var(--color);
--progress-border: #2B3044;
--progress-active: #F6F8FF;
--progress-success: #16BF78;
--tick-stroke: var(--progress-active);
--shadow: #{rgba(#00093D, .2)};
--shadow-active: #{rgba(#00093D, .32)};
font-size: 16px;
font-weight: 500;
line-height: 19px;
padding: 12px 32px;
border: 0;
border-radius: 24px;
outline: none;
user-select: none;
cursor: pointer;
backface-visibility: hidden;
-webkit-appearance: none;
-webkit-tap-highlight-color: transparent;
transition: transform .3s, box-shadow .3s;
box-shadow: 0 var(--shadow-y, 4px) var(--shadow-blur, 12px) var(--shadow);
transform: scale(var(--scale, 1));
color: var(--color);
background: var(--background);
& > div {
border-radius: 50%;
top: 12px;
left: 12px;
position: absolute;
background: var(--progress-border);
transition: transform .3s, opacity .2s;
opacity: var(--icon-o, 0);
transform: translateX(var(--icon-x, -4px));
&:before {
content: '';
width: 16px;
height: 16px;
left: 2px;
top: 2px;
z-index: 1;
position: absolute;
background: var(--background);
border-radius: inherit;
transform: scale(var(--background-scale, 1));
transition: transform .32s ease;
}
svg {
display: block;
fill: none;
width: 20px;
height: 20px;
&.progress {
transform: rotate(-90deg) scale(var(--progress-scale, 1));
transition: transform .5s ease;
circle {
stroke-dashoffset: 1;
stroke-dasharray: var(--progress-array, 0) 52;
stroke-width: 16;
stroke: var(--progress-active);
transition: stroke-dasharray var(--duration) linear;
}
}
&.tick {
left: 0;
top: 0;
position: absolute;
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
stroke: var(--tick-stroke);
transition: stroke .3s ease .7s;
polyline {
stroke-dasharray: 18 18 18;
stroke-dashoffset: var(--tick-offset, 18);
transition: stroke-dashoffset .4s ease .7s;
}
}
}
}
ul {
margin: 0;
padding: 0;
text-align: center;
pointer-events: none;
list-style: none;
min-width: 52px;
position: relative;
backface-visibility: hidden;
transition: transform .3s;
transform: translate3d(var(--ul-x, 0), 0, 0);
li {
top: var(--t, 0);
backface-visibility: hidden;
transform: translateY(var(--ul-y)) translateZ(0);
transition: transform .3s ease .16s, opacity .2s ease .16s;
&:not(:first-child) {
--o: 0;
position: absolute;
left: 0;
right: 0;
}
&:nth-child(1) {
opacity: var(--ul-o-1, 1);
}
&:nth-child(2) {
--t: 100%;
opacity: var(--ul-o-2, 0);
}
&:nth-child(3) {
--t: 200%;
opacity: var(--ul-o-3, 0);
}
}
}
&:focus,
&:hover {
&:not(.process) {
--shadow: var(--shadow-active);
--shadow-y: 8px;
--shadow-blur: 16px;
}
}
&:active {
&:not(.success) {
--scale: .96;
--shadow-y: 4px;
--shadow-blur: 8px;
}
}
&.process {
--icon-x: 0;
--ul-y: -100%;
--ul-o-1: 0;
--ul-o-2: 1;
--ul-o-3: 0;
}
&.process,
&.success {
--ul-x: 8px;
--icon-o: 1;
--progress-array: 52;
}
&.success {
--icon-x: 6px;
--progress-border: none;
--progress-scale: .11;
--tick-stroke: var(--progress-success);
--background-scale: 0;
--tick-offset: 36;
--ul-y: -200%;
--ul-o-1: 0;
--ul-o-2: 0;
--ul-o-3: 1;
& > div {
svg {
&.progress {
animation: tick .3s linear forwards .4s;
}
}
}
}
}
@keyframes tick {
100% {
transform: rotate(-90deg) translate(0, -5px) scale(var(--progress-scale));
}
}
html {
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
}
* {
box-sizing: inherit;
&:before,
&:after {
box-sizing: inherit;
}
}
// dribbble & twitter
body {
min-height: 100vh;
font-family: 'Roboto', Arial;
display: flex;
justify-content: center;
align-items: center;
background: #275EFE;
font-family: 'Roboto', Arial, sans-serif;
.dribbble {
position: fixed;
display: block;
right: 20px;
bottom: 20px;
img {
display: block;
width: 76px;
}
}
.twitter {
position: fixed;
display: block;
right: 112px;
bottom: 14px;
svg {
width: 24px;
height: 24px;
fill: white;
}
}
}
View Compiled
// Hold button with mouse / select with tab and hold spacebar
let duration = 1600,
success = button => {
//Success function
button.classList.add('success');
};
document.querySelectorAll('.button-hold').forEach(button => {
button.style.setProperty('--duration', duration + 'ms');
['mousedown', 'touchstart', 'keypress'].forEach(e => {
button.addEventListener(e, ev => {
if(e != 'keypress' || (e == 'keypress' && ev.which == 32 && !button.classList.contains('process'))) {
button.classList.add('process');
button.timeout = setTimeout(success, duration, button);
}
});
});
['mouseup', 'mouseout', 'touchend', 'keyup'].forEach(e => {
button.addEventListener(e, ev => {
if(e != 'keyup' || (e == 'keyup' && ev.which == 32)) {
button.classList.remove('process');
clearTimeout(button.timeout);
}
}, false);
});
});
This Pen doesn't use any external JavaScript resources.