Create beautiful intersection animation with TW Zen.
It can be used with frameworks - SvelteKit, Next.js, etc. - and with simple HTML pages.
- Automatically suspends the animation, when element is not intersected, saves energy.
- Turns off animations in reduced motion mode.
- Supports responsive design.
- There is no third-party dependency.
- Free and Open Source.
Check out the https://tw-zen-site.vercel.app/ page.
pnpm add -D @patoi/tw-zen-plugin
or npm install -D @patoi/tw-zen-plugin
Before using it, you need to add to tailwind.config.js
the plugin and the safelist:
plugins: [require('@patoi/tw-zen-plugin')],
safelist: ['zen--suspend', 'zen--off', 'zen--reduced']
Add classes to block-level elements. When block-level element intersected with view, animation has triggered.
Note that padding increases the size of the block-level element, so the content may not be visible on the screen yet, but the animation will begin.
zen-fade
fade-in contentzen-pop-up
content moves up with fade-inzen-from-left
content moves from left to right with fade-inzen-from-right
content moves from right to left with fade-inzen-pause zen-spin-forever
constantly rotating content
For example:
<!-- no-framework and Svelte -->
<div class="zen-once zen-pop-up">...</div>
<!-- react -->
<Image className="zen-pause zen-spin-forever" />
If you are not using a framework, just HTML/JS, then put the script at the end of the HTML page before the html element:
<script src="https://unpkg.com/@patoi/tw-zen-plugin@1.1.1/init.min.js" />
Example project: https://github.com/patoi/tw-zen-example-html
Check https://www.npmjs.com/package/@patoi/tw-zen-plugin page for latest version number.
All animations will repeat constantly unless you add zen-once
, for example: zen-once zen-pop-up
The use of zen-once
is recommended.
The zen-spin-forever
rotates the content forever, and should always be used with zen-pause
, it suspends the rotation (saving energy).
Breakpoint handling (except zen-spin-forever
):
- Turn off animation with
max-lg:zen--off
, it will not be animated belowlg
size. - Turn off animation with
lg:zen--off
, it will not be animated abovelg
size.
In case of zen-spin-forever
(or zen-custom-animation
, see later) just write max-lg:zen-spin-forever
or lg:zen-spin-forever
<div class="zen-once zen-pop-up max-lg:zen--off">...</div>
Tailwind way to customize:
<!-- delaying animation with 5s -->
<div class="zen-fade zen-once delay-[5000ms]">...</div>
<!-- animation's duration is 2s -->
<div class="zen-fade zen-once duration-[2000ms]">...</div>
To extend animations, start your style with zen-
in your base css file:
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer components {
/* fast rotating animation */
.zen-custom-animation {
@apply animate-[spin_2s_linear_infinite]
}
}
Don't forget to start the intersection handler in the code if you're using a framework! In plain HTML codes it starts automatically.
There are examples for using with frameworks.
- Next.js example: https://github.com/patoi/tw-zen-example-nextjs
- SvelteKit example: https://github.com/patoi/tw-zen-example-sveltekit