Buttons
Button 05

Info

A smooth button interaction where the original text slides out while the secondary text rotates and slides into place.

Buttons
May 8, 2026

Setup

00

Copy structure to Elementor

Right-click in Elementor, choose “Paste from another site,” and while the popup is open, press cmd/ctrl + v to insert the layout.

Copy To Elementor
Download JSON Template

Important

  • Use Elementor 3.11 or above.
  • Before copying, make sure all required widgets and features are active, including Elementor Pro widgets, Editor v4, and Flexbox Containers.
  • Safari may block clipboard access, so Chrome or Firefox is recommended for smoothest copy/paste experience.
  • If copy/paste fails, clear cache/cookies and disable any plugins or browser extensions that may interfere.
00

Add Custom CSS

Paste the code through the page or site settings, or add it via Elementor → Custom Code before body tag.

[data-oura-button-05="button"] {
  --hover-duration: 400;
  --hover-ease: cubic-bezier(0.22, 1, 0.36, 1);
}

/* default */
[data-oura-button-05="label-1"],
[data-oura-button-05="label-2"] {
  transform-origin: bottom center;
  will-change: transform;
  transition: transform 0s;
}

[data-oura-button-05="label-2"] {
  transform: translateX(-100%) translateY(46%) rotateZ(-20deg);
}

/* hover */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {

  [data-oura-button-05="button"].is-hovered [data-oura-button-05="label-1"],
  [data-oura-button-05="button"].is-hovered [data-oura-button-05="label-2"] {
    transition: transform calc(var(--hover-duration) * 1ms) var(--hover-ease);
  }

  [data-oura-button-05="button"].is-hovered [data-oura-button-05="label-1"] {
    transform: translateX(100%) translateY(46%) rotateZ(20deg);
  }

  [data-oura-button-05="button"].is-hovered [data-oura-button-05="label-2"] {
    transform: translateX(0) translateY(0) rotateZ(0);
  }
}

/* click */
[data-oura-button-05="button"] {
  transition: transform 0.2s ease;
}

[data-oura-button-05="button"]:active {
  transform: scale(0.94);
}
00

Add Custom Javascript

Paste the script through Elementor → Custom Code and set it to load after the closing body tag.

document.addEventListener("DOMContentLoaded", () => {
  document.querySelectorAll('[data-oura-button-05="button"]').forEach((button) => {
    const duration = parseFloat(
      getComputedStyle(button).getPropertyValue("--hover-duration")
    );

    let lockedUntil = 0;
    let leaveTimer;

    const setHovered = (state) => button.classList.toggle("is-hovered", state);

    button.addEventListener("mouseenter", () => {
      clearTimeout(leaveTimer);

      if (performance.now() < lockedUntil) {
        setHovered(false);
        void button.offsetWidth;
        requestAnimationFrame(() => {
          lockedUntil = performance.now() + duration;
          setHovered(true);
        });
      } else {
        lockedUntil = performance.now() + duration;
        setHovered(true);
      }
    });

    button.addEventListener("mouseleave", () => {
      const remaining = lockedUntil - performance.now();
      leaveTimer = setTimeout(() => setHovered(false), Math.max(0, remaining));
    });
  });
});
00

Publish and preview live

Some solutions only work on the live site. Always publish and test after each change, as results may not appear in the editor.