A smooth button interaction where the original text slides out while the secondary text rotates and slides into place.
Right-click in Elementor, choose “Paste from another site,” and while the popup is open, press cmd/ctrl + v to insert the layout.
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);
}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));
});
});
});Some solutions only work on the live site. Always publish and test after each change, as results may not appear in the editor.