Live preview
Preview settings
Changes appear as you type. Use Tab to test keyboard focus.
⌘ / Ctrl + S saves locally
Button Interaction(GSAP)
HTML, CSS or Tailwind, and a little JavaScript. One button or a group of up to six.
By @shraddha761
Button submission checks
Checks will appear after the preview updates.
Buttons only: no full pages, forms, cards or navigation. Put scripts in the JavaScript tab. Tailwind uses utilities from HTML and JavaScript; use complete class names. Custom CSS supports plain CSS, without @apply, imports or plugins.
Accessibility quick check
Waiting for the rendered preview…
Try Tab, Enter and Space in the preview. Check the focus ring, hover and disabled states, then enable Reduce motion. These checks are guidance, not an accessibility certification.
Explore freely here. Remix to publish your version with credit to the creator.
About Button Interaction(GSAP)
Button Interaction(GSAP) is an animated CSS button by @shraddha761. Preview the interaction, customize its HTML, styles and JavaScript, or download the files with creator credit.
- Effects and categories
- Icon
- Using this example
- Copy the HTML or download index.html, style.css and app.js. Test keyboard focus, motion and contrast in your own project.
Usage, Tailwind and licensing questions
Read the source files
HTML
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title> Button Interaction(GSAP)</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<!-- partial:index.partial.html -->
<button id="donation-btn">
<svg viewBox="0 0 512 512">
<g id="hand">
<g fill="#5adecb">
<path
d="M47.1,302h-32c-8.3,0-15,6.7-15,15v180c0,8.3,6.7,15,15,15h32c24.8,0,45-20.2,45-45V347
C92.1,322.2,71.9,302,47.1,302z"
/>
</g>
<g fill="#fefefe">
<path
d="M507.6,331.1c-1.8-3-4.2-5.4-6.9-7.5c-11-9.7-29.7-8.7-40.5,3l-68.1,78.6l-2.1,2.4
c-8.4,9.3-20.4,14.4-33,14.4H240.6c-8.4,0-15-6.6-15-15c0-8.4,6.6-15,15-15h91.5c16.5,0,30-13.5,30-30v-0.3
c-0.3-16.5-13.5-29.7-30-29.7h-54.3c-9,0-18.6-3.3-26.4-9.9c-36.6-32.1-90-34.2-129.3-6.9v184.5c29.7,8.1,60.3,12.3,91.2,12.3
h133.8c33,0,64.2-15.6,84-42l72-96C513.6,360.2,514.4,341.3,507.6,331.1z"
/>
</g>
</g>
<g id="icon-wrapper">
<g id="heart">
<circle cx="267.9" cy="139.1" r="123.9" fill="#3e3d3e" />
<g id="heart-icon" fill="#fbbabc">
<path
d="M350,76.3c-9.8-11-23.4-17.1-38.2-17.1c-16.6,0-31,7.8-41.6,22.7c-0.8,1.1-1.5,2.2-2.2,3.3
c-0.7-1.1-1.4-2.2-2.2-3.3c-10.6-14.8-25-22.7-41.6-22.7c-14.9,0-28.4,6.1-38.2,17.1c-9.3,10.4-14.4,24.4-14.4,39.3
c0,16.2,6.3,31.2,19.8,47.1c11.8,13.9,28.7,28.1,48.2,44.7c7.2,6.1,14.7,12.4,22.7,19.3c1.7,1.4,3.7,2.2,5.8,2.2
c2.1,0,4.1-0.7,5.8-2.2c7.9-6.9,15.4-13.2,22.7-19.3c12.6-10.6,23.4-19.8,32.8-28.7c18.3-17.3,35.2-36.8,35.2-63.1
C364.4,100.7,359.3,86.7,350,76.3z"
/>
<rect
x="171.6"
y="228"
width="193"
height="169.5"
clip-path="url(#clip-heart)"
fill="#fbbabc"
id="heart-progress"
/>
</g>
</g>
<g id="coin">
<circle
id="wrapper"
class="st4"
cx="267.9"
cy="139.1"
r="123.9"
fill="#bef1d3"
/>
<g id="dollar">
<path
class="st2"
d="M267.3,224.1v-14.7c-9.5-0.2-19.3-2.5-26.7-6c-3.4-1.6-5-5.5-3.7-9l0.2-0.5c1.5-4.1,6.1-5.9,10-4.1
c6.7,3.1,14.9,5.2,23.4,5.2c15.1,0,25.2-8.7,25.2-20.8c0-11.7-8.3-18.9-24-25.2c-21.6-8.5-35-18.2-35-36.7c0-17.6,12.5-31,32-34.1
V63.3c0-3.6,2.9-6.6,6.6-6.6l0,0c3.6,0,6.6,2.9,6.6,6.6v14c8.8,0.3,15.6,2,21,4.2c3.7,1.5,5.6,5.8,4.1,9.5v0
c-1.5,3.9-5.9,5.8-9.8,4.3c-4.8-2-11.4-3.8-19.8-3.8c-16.3,0-22.5,9.8-22.5,18.2c0,11,7.8,16.5,26.3,24.2
c21.8,8.9,32.9,19.9,32.9,38.8c0,16.7-11.7,32.4-33.5,36v15.4c0,3.7-3,6.7-6.7,6.7l0,0C270.3,230.8,267.3,227.8,267.3,224.1z"
/>
</g>
</g>
</g>
<g id="wallet">
<g>
<path
fill="#BCF7CF"
id="wallet-wrapper"
class="st5"
d="M418,531.2H117.8c-12.6,0-22.8,10.2-22.8,22.8v300.2c0,12.6,10.2,22.8,22.8,22.8H418
c12.6,0,22.8-10.2,22.8-22.8V554C440.8,541.4,430.6,531.2,418,531.2z M175.2,555.9c1.6-1.6,3.7-2.6,6.1-2.6h175.3
c4.8,0,8.7,3.9,8.7,8.7c0,2.4-1,4.5-2.5,6.1c-1.6,1.6-3.7,2.5-6.1,2.5H181.3c-4.8,0-8.7-3.9-8.7-8.7
C172.7,559.6,173.6,557.5,175.2,555.9z"
/>
<path
fill="#59E2C1"
d="M417.7,531.2H118.1c-12.8,0-23.1,10.4-23.1,23.1V670h345.8V554.3
C440.8,541.6,430.4,531.2,417.7,531.2z M362.8,568.1c-1.6,1.6-3.7,2.5-6.1,2.5H181.3c-4.8,0-8.7-3.9-8.7-8.7c0-2.4,1-4.5,2.5-6.1
c1.6-1.6,3.7-2.6,6.1-2.6h175.3c4.8,0,8.7,3.9,8.7,8.7C365.3,564.4,364.4,566.5,362.8,568.1z"
/>
</g>
<g id="checked-box">
<circle id="ellipse" cx="269" cy="769.2" r="69" fill="#EFB4B6"/>
<polyline
fill="none"
stroke = "#FFF"
stroke-width = "20"
stroke-linecap = "round"
id="checked-icon"
points="222.9,772.4 246.3,797.9 314.6,740.5"
/>
</g>
</g>
<defs>
<clipPath id="clip-heart">
<path
d="M350,76.3c-9.8-11-23.4-17.1-38.2-17.1c-16.6,0-31,7.8-41.6,22.7c-0.8,1.1-1.5,2.2-2.2,3.3
c-0.7-1.1-1.4-2.2-2.2-3.3c-10.6-14.8-25-22.7-41.6-22.7c-14.9,0-28.4,6.1-38.2,17.1c-9.3,10.4-14.4,24.4-14.4,39.3
c0,16.2,6.3,31.2,19.8,47.1c11.8,13.9,28.7,28.1,48.2,44.7c7.2,6.1,14.7,12.4,22.7,19.3c1.7,1.4,3.7,2.2,5.8,2.2
c2.1,0,4.1-0.7,5.8-2.2c7.9-6.9,15.4-13.2,22.7-19.3c12.6-10.6,23.4-19.8,32.8-28.7c18.3-17.3,35.2-36.8,35.2-63.1
C364.4,100.7,359.3,86.7,350,76.3z"
/>
</clipPath>
</defs>
</svg>
<div class="wrapper">
<div class="slider">
<span class="btn-text">Donate Now</span>
<span class="placeholder">
Submitting...
</span>
<span>Received</span>
<span>Donate Now</span>
</div>
</div>
</button>
<a href="https://dribbble.com/maubucardo" target="_blank">
</a>
<!-- partial -->
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.0/gsap.min.js'></script><script src="./app.js"></script>
</body>
</html>
CSS
button {
border: 0;
padding: 0;
color: #000;
border-radius: 4px;
outline: none;
cursor: pointer;
font-size: 16px;
font-weight: bold;
display: flex;
align-items: center;
overflow: hidden;
background: transparent;
box-shadow: 10px 10px rgba(0, 0, 0, 0.1);
transition: 0.1s box-shadow ease-in;
}
button svg {
background: #3f3e3c;
width: 50px;
height: 40px;
padding: 10px;
transition: 0.4s;
}
button div.wrapper {
padding: 0 25px 0 10px;
height: 60px;
overflow: hidden;
background: #f5f5f5;
}
button div.wrapper .slider {
transform: translate3d(0, 0, 0);
}
button div.wrapper .slider span {
color: #010101;
display: block;
line-height: 60px;
}
.dropped {
box-shadow: 6px 6px rgba(0, 0, 0, 0.1);
}
a {
font-weight: bold;
color: #386981;
position: absolute;
font-size: 12px;
top: 5px;
left: 50%;
transform: translateX(-50%);
}
html {
width: 100%;
height: 100%;
}
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
box-sizing: border-box;
display: grid;
place-items: center;
background: #ffc5c4;
overflow: hidden;
font-family: sans-serif;
}JavaScript
console.clear();
const hand = document.querySelector("#hand"),
coin = document.querySelector("#coin"),
btn = document.querySelector("#donation-btn"),
heart = document.querySelector("#heart"),
heartIcon = document.querySelector("#heart-icon"),
heartProgress = document.querySelector("#heart-progress"),
wallet = document.querySelector("#wallet"),
slider = document.querySelector(".slider"),
checkedBox = document.querySelector("#checked-box");
let isAnimationInAction = false;
let tl = new TimelineMax();
let hoverState = true;
btn.addEventListener("click", () => {
if (isAnimationInAction) {
return false;
}
isAnimationInAction = true;
hoverOut();
hoverState = false;
startAnimation();
heartFill();
});
let startAnimation = () => {
tl.to(coin, 0.2, { scaleX: 0, transformOrigin: "center center" }, 0.4).
to(hand, 0.6, { x: -800 }).
to(heart, 0.6, { scale: 2, transformOrigin: "center 0" }, "<").
to(slider, 0.6, { y: -60 }, ">").
to(heartIcon, 0.4, { fill: "#ececec" }, 0.2);
};
let heartFill = () => {
tl.to(heartProgress, 2.5, {
attr: { y: 59.2 },
transformOrigin: "center 0" }).
to(wallet, 1, { ease: Power1.easeOut, y: -400 }).
to(
heart,
0.4,
{
ease: Power1.easeOut,
scale: 0.5,
y: -200,
transformOrigin: "center center" },
"<").
to(slider, 0.6, { ease: Power1.easeOut, y: -120 }, "<").
to(heart, 0.8, { y: 0, scale: 0 }).
fromTo(
checkedBox,
0.4,
{ scaleX: 0, scaleY: 0, transformOrigin: "center center" },
{
scaleX: 1,
scaleY: 1,
transformOrigin: "center center",
onComplete: () => {
setTimeout(() => {
received();
}, 2500);
} });
};
let received = () => {
tl.to(hand, 0.8, { x: 0 }).
to(wallet, 0.4, { y: 0, transformOrigin: "center center" }, "<").
to(slider, 0.6, { ease: Power1.easeOut, y: -180 }, ">").
set(heart, { clearProps: "all" }).
set(heartProgress, { attr: { y: 298 } }).
set(slider, { y: 0 }).
to(coin, 0.2, {
scaleX: 1,
transformOrigin: "center center",
onComplete: function () {
isAnimationInAction = false;
hoverState = true;
tl.clear();
} });
};
function hoverIn() {
btn.classList.add("dropped");
}
function hoverOut() {
btn.classList.remove("dropped");
}
btn.addEventListener("mouseenter", function () {
if (hoverState) {
hoverIn();
}
});
btn.addEventListener("mouseleave", hoverOut);