Back to buttons

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

Remix button

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);