Move the mouse over the squares below to launch the animation.
Important: If you want to use one of the animations above
you got to add their name in object safelist
in
theme
of your tailwind.config.js
.
For example:
safelist: ['animate-[fade-in_1s_ease-in-out]',
'animate-[fade-in-down_1s_ease-in-out]']
.
To delve into a more detailed exploration of extended animations, we recommend directing your attention to the Animations Extended documentation. This resource provides a thorough overview and in-depth insights into the various extended animation options available, empowering you to create engaging and dynamic visual experiences for your web projects.
Basic example
The easiest way to implement the animation is to use
TEAnimation
component. In the example below, we wrapped
the simple svg
with TEAnimation
and added
animation
and reset
properties to give it
animation on click. We didn't set start
property, because
it's set to onClick
by default.
-
animation
- specify which animation apply to the element. In the demo section above you can find available animations. -
reset
- specify if the animation can be repeated. -
start
- specify how to run the animation. By default it's set toonClick
.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsBasicExample(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
reset
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
Launch options
There are several options for launching the animation.
On click
The animation will be launched when the element is clicked. This is the default launching option.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsOnClick(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
reset
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
On hover
Use start="onHover"
to launch the animation on mouse
hover.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsOnHover(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="onHover"
reset
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
On load
Use start="onLoad"
to start the animation after loading
the page. Refresh your browser to see this effect.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsOnLoad(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="onLoad"
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
Manually
Use start="manually"
to initialize component without
animating, adding hover, clicking or scrolling events and use the
toggle
property to start/end the animation.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsManually(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="manually"
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
On scroll
Use start="onScroll"
to launch the animation when you
scroll the page and reach the element. Notice that the animation
will launch only once - even if you reach it when
scrolling multiple times.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsOnScroll(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="onScroll"
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
Repeat animation on scroll
If you want to launch the animation every time it's reached when
scrolling use repeatOnScroll
prop.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsRepeatOnScroll(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
Show on load
Use showOnLoad
property to show element and animation
on page load.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsShowOnLoad(): JSX.Element {
return (
<div className="flex justify-center">
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
showOnLoad
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
);
}
Examples
Examples of practical usage of the animation.
Launching via external element
Click or hover the button to launch the animation.
import React, { useState } from "react";
import { TEAnimation, TERipple } from "tw-elements-react";
export default function AnimationsLaunchingExternal(): JSX.Element {
const [clicked, setClicked] = useState(false);
const [hovered, setHovered] = useState(false);
const handleClick = () => {
setClicked(true);
setTimeout(() => {
setClicked(false);
}, 1000);
};
const handleHover = () => {
setHovered(true);
setTimeout(() => {
setHovered(false);
}, 1000);
};
return (
<div className="flex flex-col items-center justify-around md:flex-row">
<div className="flex items-center space-x-2">
<TERipple rippleColor="light">
<button
type="button"
onClick={handleClick}
className="rounded bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Animation on click
</button>
</TERipple>
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="manually"
toggle={clicked}
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
<div className="flex items-center space-x-2">
<TERipple rippleColor="light">
<button
type="button"
onMouseEnter={handleHover}
className="rounded bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Animation on hover
</button>
</TERipple>
<TEAnimation
animation="[slide-right_1s_ease-in-out]"
start="manually"
toggle={hovered}
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
</div>
</div>
);
}
Start animation manually
You can use toggle
property to start/end the animation
import React, { useState } from "react";
import { TEAnimation, TERipple } from "tw-elements-react";
export default function AnimationsStartManually(): JSX.Element {
const [toggle, setToggle] = useState(false);
const handleStart = () => {
setToggle(true);
};
const handleStop = () => {
setToggle(false);
};
return (
<div className="flex flex-col items-center justify-around md:flex-row">
<div className="flex items-center space-x-2">
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="manually"
toggle={toggle}
repeat={true}
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
<TERipple rippleColor="light">
<button
type="button"
onClick={handleStart}
className="rounded bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Start
</button>
</TERipple>
<TERipple rippleColor="light">
<button
type="button"
onClick={handleStop}
className="rounded bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Stop
</button>
</TERipple>
</div>
</div>
);
}
Change animation type
You can change the element's animation type at any time.
import React, { useState } from "react";
import { TEAnimation, TERipple } from "tw-elements-react";
export default function AnimationsChangeType(): JSX.Element {
const [changeAnimation, setChangeAnimation] = useState(false);
const handleClick = () => {
setChangeAnimation((prevAnimation) => !prevAnimation);
};
return (
<div className="flex justify-center items-center space-x-2">
<TEAnimation
animation={
changeAnimation
? "[fade-in_1s_ease-in-out]"
: "[fade-out_1s_ease-in-out]"
}
start="onLoad"
repeat={true}
className="[&>svg]:w-11"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 24 24"
fill="currentColor"
>
<path d="M3.478 2.405a.75.75 0 00-.926.94l2.432 7.905H13.5a.75.75 0 010 1.5H4.984l-2.432 7.905a.75.75 0 00.926.94 60.519 60.519 0 0018.445-8.986.75.75 0 000-1.218A60.517 60.517 0 003.478 2.405z" />
</svg>
</TEAnimation>
<TERipple rippleColor="light">
<button
type="button"
onClick={handleClick}
className="rounded bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Change animation
</button>
</TERipple>
</div>
);
}
Fading gallery
With animation on scroll you can create an impressive gallery that
will appear smoothly step by step. In the example below, we
additionally use delay
prop on some images to make it
appears one by one.
import React from "react";
import { TEAnimation } from "tw-elements-react";
export default function AnimationsFadingGallery(): JSX.Element {
return (
<div className="grid grid-cols-3 gap-4">
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
delay={300}
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
delay={500}
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
delay={300}
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
<TEAnimation
animation="[fade-in_1s_ease-in-out]"
start="onScroll"
repeatOnScroll
delay={500}
>
<img
src="https://tecdn.b-cdn.net/img/new/standard/city/041.webp"
className="rounded"
/>
</TEAnimation>
</div>
);
}
List group
Click "Add" button to add a new item to the list.
import React, { useState } from "react";
import { TEAnimation, TERipple } from "tw-elements-react";
export default function AnimationsListGroup(): JSX.Element {
const [canAnimate, setCanAnimate] = useState(true);
const [list, setList] = useState([
"An item",
"A second item",
"A third item",
"A fourth item",
"And a fifth one",
]);
const addListRow = () => {
if (!canAnimate) {
return;
}
setCanAnimate(false);
setList([...list, `element ${list.length}`]);
setTimeout(() => {
setCanAnimate(true);
}, 1000);
};
const removeListRow = (id: number) => {
if (!canAnimate) {
return;
}
setCanAnimate(false);
const element = document.getElementById(`list-group-item-${id}`);
const prevElement = element?.previousElementSibling
? element.previousElementSibling
: element;
const animation =
element === prevElement
? "[fade-out_1s_ease-in-out]"
: "[slide-out-up_1s_ease-in-out]";
element?.classList.add(`animate-${animation}`);
setTimeout(() => {
element?.classList.remove(`animate-${animation}`);
setList(list.filter((_, i) => i !== id));
setCanAnimate(true);
}, 1000);
};
return (
<div className="flex justify-center">
<div className="flex items-start min-w-[22rem]">
<ul
id="list-group"
className="w-96 overflow-hidden rounded-lg border border-neutral-200 bg-white text-neutral-900 dark:bg-neutral-600 dark:text-neutral-200"
>
{list.map((el, i) => {
return (
<TEAnimation
id={`list-group-item-${i}`}
key={el}
tag="li"
animation="[slide-in-down_1s_ease-in-out]"
reset
start="onLoad"
onClick={() => removeListRow(i)}
style={{ zIndex: `${list.length - i}` }}
className="relative w-full border-neutral-200 bg-white px-6 py-2 dark:bg-neutral-600 [&:not(:last-child)]:border-b"
>
{el}
</TEAnimation>
);
})}
</ul>
<TERipple rippleColor="light">
<button
type="button"
onClick={addListRow}
className="rounded ms-3 bg-[#3b71ca] px-6 py-2.5 text-xs font-medium uppercase leading-tight text-white shadow-[0_4px_9px_-4px_#3b71ca] transition duration-150 ease-in-out hover:bg-[#386bc0] hover:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:bg-[#386bc0] focus:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)] focus:outline-none focus:ring-0 active:bg-[#3566b6] active:shadow-[0_8px_9px_-4px_rgba(59,113,202,0.3),0_4px_18px_0_rgba(59,113,202,0.2)]"
>
Add
</button>
</TERipple>
</div>
</div>
);
}
Related resources
If you are looking for more advanced options, try Bootstrap Animations from MDBootstrap.