Unified declarative visual effects via the data-effect attribute. Text styling, motion, backgrounds, and display effects.
Unified Effect System
The data-effect attribute is the single entry point for all visual effects in Vanilla Breeze. Instead of separate data-blink, data-glitch, data-shimmer attributes, every effect is activated through one unified attribute.
Scroll-trigger gallery: for every entrance-slot effect (fade-in, slide-up, slide-in, pop, blur-reveal, reveal, scramble, typewriter) fired under data-trigger="scroll", see the scroll-effect gallery. For continuous scroll-linked variants, see data-trigger="view-progress".
<h1 data-effect="glitch">Glitchy Heading</h1><p data-effect="reveal" data-trigger="scroll">Revealed on scroll</p><span data-effect="shimmer" class="slow">Slow shimmer</span>
How it works
| Concept | Attribute / Mechanism | Example |
| Effect name | data-effect="name" | data-effect="glitch" |
| Activation trigger | data-trigger | data-trigger="scroll", data-trigger="hover" |
| Variants & modifiers | class | class="slow", class="line", class="red animate" |
| Fine-tuning | CSS custom properties via style | style="--vb-reveal-delay: 120ms" |
Multiple effects
Apply multiple effects to a single element with space-separated values:
<h1 data-effect="gradient-text shimmer">Gradient + Shimmer</h1><h1 data-effect="pop neon outline" class="green">Entrance + glow + stroke</h1><p data-effect="text-3d bounce" class="gold">3D shadow + bouncing</p>
Composition: animation slots
Try it: the Effects Lab is an interactive composer — toggle effects across slots, swap class modifiers, and watch the generated HTML + composed animation property update live.
Every animated effect publishes into one of four animation slots. A single composer rule on [data-effect] reads all four into a comma-separated animation shorthand, so cross-category pairs compose automatically:
| Slot | Examples | Lifecycle |
entrance | fade-in, slide-up, pop, slide-in, shadow | One-shot, forwards. Fires once on activation. |
attention | shake, pulse, bounce, blink | Repeating, attention-grabbing. |
decoration | neon, outline.glow, text-3d.animate, rainbow, gradient-text.animate, shimmer, glow, float | Continuous / infinite. Static paint survives loss of the slot. |
exit | fade-out, collapse, slide-out | One-shot, forwards. |
Cross-slot composition is automatic
Effects in different slots compose with no extra work — they each occupy their own animation, so neither steals from the other:
<h1 data-effect="pop neon" class="green">Entrance + decoration</h1><span data-effect="outline float" class="thick">Static stroke + decoration motion</span><p data-effect="text-3d bounce" class="gold">Decoration + attention</p><li data-effect="fade-in slide-up" data-trigger="scroll">Two entrance effects — merged via a shared keyframe</li>
Intra-slot collisions
Two effects in the same slot share one animation. A small number of pairs ship pre-merged keyframes (e.g. fade-in + slide-up, shimmer + gradient-text). For ad-hoc combinations the second selector wins by source order — pick one, or write your own composite selector. Effects that paint static visuals outside the animation (hard-shadow, text-3d without .animate, outline without .glow, stamp) never collide.
Static paint survives slot loss
Decoration effects (neon, outline.glow, text-3d.animate, rainbow) keep their visual when the slot is occupied by something else (e.g. by a custom user animation). The pulse stops, the glow stays — only the motion is lost, not the paint.
Semantic conflicts (cross-slot)
The slot system guarantees that two effects in different slots will both run — animation timelines never clobber each other. It does not guarantee they'll look harmonious. When two effects target the same CSS property, the later slot wins per frame (slot order is entrance → attention → decoration → exit). When one effect's animation makes the element invisible, decorations underneath have nothing to show during that interval. These are intentional limits, not bugs.
| Conflict | Effects involved | What you'll see |
| Opacity flicker hides decoration |
blink + neon, blink + shimmer, blink + rainbow, etc. |
blink drives opacity 1 ↔ 0 with steps(1). The decoration keeps animating, but you only see it during blink's "on" half. Net effect: blinking decoration, which is often not what was intended. |
| Exit erases decoration mid-flight |
fade-out + decoration, collapse + decoration, slide-out + decoration |
Exit animations drop opacity (or max-block-size) to 0 with forwards. Any decoration still running gets carried to invisible along with the element. |
| Attention transform wins during entrance |
pop + bounce, slide-up + shake, slide-in + pulse |
Both slots animate transform. Attention is later in slot order, so it overrides the entrance's transform from frame zero — the entrance scale/translate is suppressed and the attention motion is what you see. The entrance's opacity animation still runs cleanly because attention doesn't touch opacity. |
| Decoration transform wins after entrance |
pop + float, slide-up + float |
Same pattern as above for the entrance phase. Once the entrance ends (forwards snaps to its final transform), the decoration's continuous transform takes over — usually the desired outcome. |
| Background-clip stack collides |
shimmer + gradient-text, shimmer + marquee |
Both effects own the background-image + -webkit-background-clip: text stack. We ship a merged keyframe for shimmer + gradient-text; arbitrary pairs need a bespoke selector. |
Workarounds:
- Pick one effect per perceptual axis. "Make it flash" and "make it shimmer" answer the same question two ways. Choose the one that fits the message.
- Sequence with the lifecycle hooks. Use
VB.onPhaseEnd(el, 'entrance', …) to add an attention or decoration class only after the entrance finishes — see the Lifecycle JS API.
- Write a bespoke composite selector that merges the two effects' declarations into a single coherent CSS rule — that's how
fade-in + slide-up and shimmer + gradient-text are handled in the framework.
Lifecycle JS API
The slot system is paired with a small JS surface for cross-effect coordination:
| Method | Signature | Use |
VB.activate(el) | (el) => void | Add data-effect-active and fire entrance/attention. Programmatic trigger. |
VB.deactivate(el) | (el) => void | Remove data-effect-active; slot vars un-publish, animations stop. |
VB.onPhaseEnd(el, phase, fn) | (el, phase, fn) => unsubscribe | Run fn when any keyframe in phase finishes (entrance/exit fire once; finite attention also fires). |
VB.registerKeyframe(name, phase) | (name, phase) => void | Map a custom keyframe to a phase so animationend classification works for it. |
| Event | Fired on | Detail |
vb:effect-phase-end | Element with [data-effect] | { phase, animationName } — phase is entrance | exit | attention | decoration. |
vb:phase-change | Element when activated/deactivated | { active: true | false }. |
vb:vt-update-done | Elements with [data-trigger~="vt"] | Fired by VB.swap() after the view transition's updateCallbackDone resolves. |
const el = document.querySelector('[data-effect~="pop"]');VB.onPhaseEnd(el, 'entrance', () => { startTypewriter(el);});
data-effect="blink" core
Text flashes on and off with a step animation, toggling between full and 50% opacity.
<span data-effect="blink">Signal Active</span><span data-effect="blink" class="slow">Standby Mode</span><span data-effect="blink" class="fast">Alert!</span>
| Attribute / Class | Values | Description |
data-effect="blink" | — | Enables the blink effect (1s default rate). |
class="slow" | — | Slow blink (2s cycle). |
class="fast" | — | Fast blink (0.4s cycle). |
| CSS Property | Default | Description |
--vb-blink-rate | 1s | Duration of one blink cycle. |
data-effect="blur-reveal" effects
Words start blurred and transition to clear instead of sliding up. Creates a dreamy, focus-pull effect. Triggers on scroll.
<h1 data-effect="blur-reveal" data-trigger="scroll">Text emerges from a soft blur</h1><h2 data-effect="blur-reveal" data-trigger="scroll" style="--vb-blur-reveal-delay: 120ms">Slower blur-to-clear transition</h2><p data-effect="blur-reveal" data-trigger="scroll" class="line">Line-by-line blur reveal creates a dreamy effect.</p>
| Attribute / Class | Values | Description |
data-effect="blur-reveal" | — | Enables the blur reveal effect. Use with data-trigger="scroll". |
class="word" | — | Word-by-word split mode (default). |
class="line" | — | Line-by-line split mode. |
| CSS Property | Default | Description |
--vb-blur-reveal-delay | 80ms | Stagger delay between chunks. |
data-effect="bounce"
Continuous vertical bounce animation. The element bounces up and down in a rhythmic loop. The kawaii pack overrides this with a spring-loaded hover-only variant when loaded.
<button data-effect="bounce">Bouncing Button</button><span data-effect="bounce" class="slow">Slow bounce</span><span data-effect="bounce" style="--vb-bounce-height: 20px; display: inline-block;">Big bounce</span>
| Attribute / Class | Values | Description |
data-effect="bounce" | — | Enables the bounce animation (continuous loop). |
class="slow" | — | Slower bounce cycle. |
class="fast" | — | Faster bounce cycle. |
| CSS Property | Default | Description |
--vb-bounce-height | 12px | Maximum bounce height. |
--vb-duration | 1s | Duration of one bounce cycle. |
data-effect="collapse"
Height-to-zero exit animation. The element collapses vertically while fading out, then stays hidden. Useful for dismissible alerts, list item removal, or accordion-style closing.
<p data-effect="collapse" data-trigger="click">Click this paragraph to collapse it.</p><p data-effect="collapse" data-trigger="time:4000">This collapses after 4 seconds.</p>
| Attribute / Class | Values | Description |
data-effect="collapse" | — | Enables the collapse exit effect. Activates when data-effect-active is set. |
data-trigger="click" | — | Collapse on click. |
data-trigger="time:n" | — | Collapse after n milliseconds. |
class="slow" | — | Slower collapse duration. |
| CSS Property | Default | Description |
--vb-collapse-height | 500px | Starting max-height. Set to the element's natural height for a smoother animation. |
--vb-duration | 300ms | Duration of the collapse animation. |
data-effect="fade-in"
Simple opacity fade entrance. Element transitions from transparent to fully visible. Commonly used with data-trigger="scroll" for scroll-triggered reveals.
<h1 data-effect="fade-in" data-trigger="scroll">Fades in on scroll</h1><p data-effect="fade-in" data-trigger="scroll" class="slow">Slow fade entrance</p>
| Attribute / Class | Values | Description |
data-effect="fade-in" | — | Enables the fade-in effect. Use with data-trigger="scroll". |
class="slow" | — | Slower fade duration. |
class="fast" | — | Faster fade duration. |
| CSS Property | Default | Description |
--vb-fade-in-duration | 0.6s | Duration of the fade animation. |
data-effect="fade-out"
Opacity fade exit. Element transitions from visible to transparent. Use with data-trigger="click" or data-trigger="time:n".
<p data-effect="fade-out" data-trigger="scroll">Fades out as you scroll past</p>
| Attribute / Class | Values | Description |
data-effect="fade-out" | — | Enables the fade-out effect. Use with data-trigger="scroll". |
| CSS Property | Default | Description |
--vb-fade-out-duration | 0.6s | Duration of the fade-out animation. |
data-effect="flipboard" core
Split-flap departure board effect. Each character sits in a dark cell with a horizontal hinge and cycles through random letters before settling on the target. Requires JS.
<p data-effect="flipboard">DEPARTURES</p><p data-effect="flipboard">GATE 42</p><p data-effect="flipboard">ON TIME</p>
| Attribute / Class | Values | Description |
data-effect="flipboard" | — | Enables the split-flap effect on the element's text content. |
| CSS Property | Default | Description |
--vb-flip-ms | 60ms | Duration of each character flip animation. |
data-effect="float"
Gentle vertical floating animation. The element bobs up and down in a smooth loop, creating a weightless or hovering appearance.
<span data-effect="float">Floating element</span><span data-effect="float" class="slow">Slow float</span>
| Attribute / Class | Values | Description |
data-effect="float" | — | Enables the floating animation. |
class="slow" | — | Slower float cycle. |
class="fast" | — | Faster float cycle. |
| CSS Property | Default | Description |
--vb-float-duration | 3s | Duration of one float cycle. |
--vb-float-distance | 10px | Vertical distance of the float movement. |
data-effect="glitch" effects
Chromatic aberration glitch with cyan/red channel splitting via CSS pseudo-elements. Tiny JS sets a data-glitch-text attribute for the pseudo-element content.
<h1 data-effect="glitch">System Error</h1><h2 data-effect="glitch" data-trigger="hover">Hover Me for Glitch</h2>
| Attribute / Class | Values | Description |
data-effect="glitch" | — | Enables the glitch effect (always-on by default). |
data-trigger="hover" | — | Glitch only on hover. |
data-effect="gradient-text"
CSS-only gradient coloring with theme-aware defaults and preset palettes. Add class="animate" for a flowing animation.
<h1 data-effect="gradient-text">Beautiful Gradient Text</h1><h2 data-effect="gradient-text" class="sunset">Warm Sunset Gradient</h2><h2 data-effect="gradient-text" class="ocean">Cool Ocean Gradient</h2><h2 data-effect="gradient-text" class="forest">Deep Forest Gradient</h2><h2 data-effect="gradient-text" class="neon">Electric Neon Gradient</h2><h1 data-effect="gradient-text" class="animate">Flowing Gradient Animation</h1>
| Attribute / Class | Values | Description |
data-effect="gradient-text" | — | Enables gradient text. Empty uses theme primary→secondary. |
class="sunset" | — | Warm sunset gradient palette. |
class="ocean" | — | Cool ocean gradient palette. |
class="forest" | — | Deep forest gradient palette. |
class="neon" | — | Electric neon gradient palette. |
class="animate" | — | Enable flowing gradient animation. |
data-effect="glow"
Pulsing drop-shadow glow that alternates between a subtle and intense luminance. Uses filter: drop-shadow() with color-mix() for smooth color transitions. Defaults to the theme's primary color.
<h2 data-effect="glow">Glowing text</h2><h2 data-effect="glow" style="--vb-glow-color: oklch(65% 0.28 25);">Red glow</h2><button data-effect="glow">Attention needed</button>
| Attribute / Class | Values | Description |
data-effect="glow" | — | Enables the pulsing glow animation (2s default cycle). |
class="slow" | — | Slower glow pulse. |
class="fast" | — | Faster glow pulse. |
| CSS Property | Default | Description |
--vb-glow-color | var(--color-primary) | Glow color. Any CSS color value. |
--vb-duration | 2s | Duration of one glow pulse cycle. |
data-effect="hard-shadow" core
Hard-edged offset text shadows with no blur. Choose single, double, or long trailing shadows with optional color presets. Sets font-weight: 900.
<h1 data-effect="hard-shadow">Hard Shadow</h1><h2 data-effect="hard-shadow" class="double">Double Shadow</h2><h2 data-effect="hard-shadow" class="long">Long Shadow</h2><h2 data-effect="hard-shadow" class="long red">Long Red</h2>
| Attribute / Class | Values | Description |
data-effect="hard-shadow" | — | Enables the hard shadow effect (single shadow default). |
class="double" | — | Double shadow style. |
class="long" | — | Long trailing shadow style. |
class="red", "blue", "gold", "green" | — | Shadow color preset. Combine with style classes. |
| CSS Property | Default | Description |
--vb-shadow-color | oklch(20% 0 0) | Shadow color. |
--vb-shadow-offset | 3px | Base shadow offset distance. |
data-effect="highlight"
Animated underline, box fill, or circle highlight that draws in when scrolled into view.
<p>This text has an <span data-effect="highlight" data-trigger="scroll">animated underline</span> that draws in on scroll.</p><p>Highlight <mark data-effect="highlight" data-trigger="scroll" class="box">important phrases</mark> with a background fill.</p><p>Draw attention to <span data-effect="highlight" data-trigger="scroll" class="circle">key words</span> with a circle.</p>
| Attribute / Class | Values | Description |
data-effect="highlight" | — | Enables the highlight effect. Use with data-trigger="scroll". Default style is underline. |
class="underline" | — | Underline highlight style (default). |
class="box" | — | Background fill highlight style. |
class="circle" | — | Circle highlight style. |
| CSS Property | Default | Description |
--vb-highlight-color | currentColor | Override the highlight color. |
data-effect="marquee" core
Continuously scrolling horizontal content with edge masking. Children animate left (or right with class="reverse") in an infinite loop.
<div data-effect="marquee"> <span>Breaking News</span> <span>Latest Headlines</span> <span>Stay Tuned</span> <span>More Updates</span></div>
| Attribute / Class | Values | Description |
data-effect="marquee" | — | Enables the marquee scroll effect. |
class="reverse" | — | Scroll direction reversed (right-to-left becomes left-to-right). |
class="slow" | — | Slow scroll speed (40s cycle). |
class="fast" | — | Fast scroll speed (8s cycle). |
class="pause" | — | Paused state. |
class="hover-pause" | — | Pause animation on hover. |
| CSS Property | Default | Description |
--vb-marquee-speed | 20s | Scroll animation duration. |
--vb-marquee-gap | var(--size-xl, 3rem) | Gap between repeating items. |
data-effect="neon" core
Glowing neon text with a pulsing text-shadow halo that breathes in and out over 2.5 seconds.
<h2 data-effect="neon">Neon Glow</h2><h2 data-effect="neon" class="pink">Pink Neon</h2><h2 data-effect="neon" class="cyan">Cyan Neon</h2>
| Attribute / Class | Values | Description |
data-effect="neon" | — | Enables the neon glow effect. Empty uses theme primary. |
class="pink" | — | Pink neon color. |
class="cyan" | — | Cyan neon color. |
class="green" | — | Green neon color. |
class="amber" | — | Amber neon color. |
class="red" | — | Red neon color. |
| CSS Property | Default | Description |
--vb-neon-color | Per preset | The glow color in OKLCH. |
--vb-neon-spread | 0.04em | Glow blur radius. |
data-effect="outline" core
Hollow outlined text with transparent fill using -webkit-text-stroke. Gracefully skipped via @supports.
<h1 data-effect="outline">Outline Text</h1><h2 data-effect="outline" class="thick">Thick Outline</h2><h2 data-effect="outline" class="glow">Glowing Outline</h2>
| Attribute / Class | Values | Description |
data-effect="outline" | — | Enables the outline text effect (1px default). |
class="thick" | — | Thick stroke (2px). |
class="ultra" | — | Ultra thick stroke (3px). |
class="glow" | — | Glowing outline mode. |
| CSS Property | Default | Description |
--vb-outline-width | 1px | Stroke width. |
--vb-outline-color | var(--color-text) | Stroke color. |
data-effect="particles" kawaii
JS-driven floating particle effect. Spawns emoji characters (✦ ✧ ⋆ ♡ ☆) that float upward and fade out. Requires JS.
<section data-effect="particles"> <p>Floating sparkle particles rise from the bottom.</p></section>
| Attribute / Class | Values | Description |
data-effect="particles" | — | Enables floating particle spawning. |
data-effect="pop"
Quick scale-up pop animation. The element rapidly scales from small to full size with a slight overshoot, creating a punchy entrance or interaction response.
<button data-effect="pop" data-trigger="hover">Pop on hover</button><span data-effect="pop" data-trigger="scroll">Pop on scroll</span>
| Attribute / Class | Values | Description |
data-effect="pop" | — | Enables the pop effect. |
data-trigger="hover" | — | Pop on hover. |
data-trigger="scroll" | — | Pop when scrolled into view. |
| CSS Property | Default | Description |
--vb-pop-scale | 1.15 | Maximum scale overshoot. |
--vb-pop-duration | 0.3s | Duration of the pop animation. |
data-effect="pulse"
Rhythmic scale pulse that grows and shrinks in a continuous loop. Useful for drawing attention to call-to-action elements.
<span data-effect="pulse">Pulsing element</span><span data-effect="pulse" class="slow">Slow pulse</span><span data-effect="pulse" class="fast">Fast pulse</span>
| Attribute / Class | Values | Description |
data-effect="pulse" | — | Enables the pulse animation (2s default cycle). |
class="slow" | — | Slow pulse (3s cycle). |
class="fast" | — | Fast pulse (1s cycle). |
| CSS Property | Default | Description |
--vb-pulse-duration | 2s | Duration of one pulse cycle. |
--vb-pulse-scale | 1.05 | Maximum scale of the pulse. |
data-effect="rainbow" core
Continuous hue-rotation filter that cycles through the full color spectrum.
<h1 data-effect="rainbow">Rainbow Cycling</h1><h2 data-effect="rainbow" class="slow">Slow Rainbow</h2><h2 data-effect="rainbow" class="fast">Fast Rainbow</h2>
| Attribute / Class | Values | Description |
data-effect="rainbow" | — | Enables rainbow cycling (4s default). |
class="slow" | — | Slow cycle (8s). |
class="fast" | — | Fast cycle (1.5s). |
| CSS Property | Default | Description |
--vb-rainbow-speed | 4s | Duration of one full hue cycle. |
data-effect="reveal"
Word-by-word or line-by-line entrance animation. Text slides up and fades in with staggered timing when scrolled into view.
<h1 data-effect="reveal" data-trigger="scroll">Welcome to the future of text animation</h1><h2 data-effect="reveal" data-trigger="scroll" style="--vb-reveal-delay: 120ms">Each word appears with a longer pause</h2><p data-effect="reveal" data-trigger="scroll" class="line">Line-by-line reveal guides the eye down the page.</p>
| Attribute / Class | Values | Description |
data-effect="reveal" | — | Enables the reveal effect. Use with data-trigger="scroll". |
class="word" | — | Word-by-word split mode (default). |
class="line" | — | Line-by-line split mode. |
| CSS Property | Default | Description |
--vb-reveal-delay | 80ms | Stagger delay between chunks. |
--vb-reveal-duration | 400ms | Animation duration per chunk. |
data-effect="scramble" effects
Characters resolve left-to-right from random symbols. Think Hollywood decryption or sci-fi terminal output. Triggers on scroll.
<h1 data-effect="scramble" data-trigger="scroll">Decoding the future</h1><h2 data-effect="scramble" data-trigger="scroll" style="--vb-scramble-duration: 2.5s; --vb-scramble-chars: '01'">Binary transmission</h2>
| Attribute / Class | Values | Description |
data-effect="scramble" | — | Enables the scramble effect. Use with data-trigger="scroll". |
| CSS Property | Default | Description |
--vb-scramble-duration | 1.5s | Total scramble duration. |
--vb-scramble-chars | !<>-_\\/[]{}=+*^?# | Character set for random characters. |
--vb-scramble-speed | 30ms | Frame interval. |
data-effect="shadow"
Elevated box-shadow decoration with a subtle lift animation. The element rises slightly and gains depth, transitioning from a light shadow to a more pronounced elevated shadow. Ideal for cards, panels, and call-to-action containers.
<article data-effect="shadow" data-trigger="scroll"> <h2>Elevated Card</h2> <p>Lifts with a shadow when scrolled into view.</p></article><article data-effect="shadow" style="--vb-shadow: 0 12px 32px oklch(55% 0.2 260 / 0.25);"> <h2>Custom Shadow</h2> <p>A branded shadow via --vb-shadow.</p></article>
| Attribute / Class | Values | Description |
data-effect="shadow" | — | Enables the shadow lift effect. |
data-trigger="scroll" | — | Lift when scrolled into view. |
class="slow" | — | Slower lift duration. |
| CSS Property | Default | Description |
--vb-shadow | 0 8px 24px oklch(0% 0 0 / 0.18) | Final elevated box-shadow. Override for branded shadows. |
--vb-duration | 400ms | Duration of the lift animation. |
data-effect="shake"
Rapid horizontal shaking animation. Useful for error states, attention-grabbing, or playful interactions. Runs continuously or on hover.
<span data-effect="shake">Shaking text</span><button data-effect="shake" data-trigger="hover">Shake on hover</button>
| Attribute / Class | Values | Description |
data-effect="shake" | — | Enables the shake effect (continuous by default). |
data-trigger="hover" | — | Shake only on hover. |
| CSS Property | Default | Description |
--vb-shake-intensity | 4px | Horizontal displacement distance. |
--vb-shake-duration | 0.4s | Duration of one shake cycle. |
data-effect="shimmer"
CSS-only shimmering highlight that sweeps across the text on a loop.
<h1 data-effect="shimmer">Shimmering Text Effect</h1><h2 data-effect="shimmer" class="slow">Slow and Steady Shimmer</h2><h2 data-effect="shimmer" class="fast">Quick Flash Shimmer</h2>
| Attribute / Class | Values | Description |
data-effect="shimmer" | — | Enables the shimmer effect (2s default cycle). |
class="slow" | — | Slow shimmer speed. |
class="fast" | — | Fast shimmer speed. |
data-effect="slide-in"
Horizontal entrance animation that respects text direction. In LTR, the element slides in from the left; in RTL, from the right. Uses :where([dir="rtl"]) for automatic direction support.
<h1 data-effect="slide-in">Slides in from the left</h1><h2 data-effect="slide-in" data-trigger="scroll">Appears on scroll</h2><p data-effect="slide-in" data-trigger="scroll" style="--vb-slide-distance: 80px;">From further away</p>
| Attribute / Class | Values | Description |
data-effect="slide-in" | — | Enables horizontal entrance. Use with data-trigger="scroll". |
class="slow" | — | Slower slide duration. |
class="fast" | — | Faster slide duration. |
| CSS Property | Default | Description |
--vb-slide-distance | 40px | Horizontal offset distance. |
--vb-duration | 400ms | Duration of the slide animation. |
data-effect="slide-out"
Horizontal exit animation. The element slides out in the inline-end direction while fading. Mirrors slide-in with reversed direction and RTL support via :where([dir="rtl"]).
<p data-effect="slide-out" data-trigger="click">Click to slide out</p><p data-effect="slide-out" class="slow" data-trigger="click">Slow slide out</p>
| Attribute / Class | Values | Description |
data-effect="slide-out" | — | Enables horizontal exit. Activates when data-effect-active is set. |
data-trigger="click" | — | Slide out on click. |
class="slow" | — | Slower slide duration. |
| CSS Property | Default | Description |
--vb-slide-distance | 40px | Horizontal offset distance. |
--vb-duration | 400ms | Duration of the slide animation. |
data-effect="slide-up"
Element slides upward into its final position while fading in. A clean, modern entrance animation commonly paired with scroll triggering.
<h2 data-effect="slide-up" data-trigger="scroll">Slides up into view</h2><p data-effect="slide-up" data-trigger="scroll" class="slow">Slow slide entrance</p>
| Attribute / Class | Values | Description |
data-effect="slide-up" | — | Enables the slide-up entrance. Use with data-trigger="scroll". |
class="slow" | — | Slower slide duration. |
class="fast" | — | Faster slide duration. |
| CSS Property | Default | Description |
--vb-slide-up-distance | 20px | Starting offset distance below final position. |
--vb-slide-up-duration | 0.6s | Duration of the slide animation. |
data-effect="sparkle" kawaii
CSS-only floating sparkle stars. Two ✦ characters orbit the element with staggered float animations — one gold at top-right, one lavender at bottom-left.
<span data-effect="sparkle">Sparkle Text</span><button data-effect="sparkle">Sparkle Button</button><h2 data-effect="sparkle">Sparkle Heading</h2>
| Attribute / Class | Values | Description |
data-effect="sparkle" | — | Adds floating sparkle stars via pseudo-elements. |
data-effect="stamp" core
Rubber stamp effect with fractal noise SVG filter, rotation, and mix-blend-mode: multiply. Requires JS for the SVG filter injection.
<span data-effect="stamp">APPROVED</span><span data-effect="stamp" class="blue">CLASSIFIED</span><span data-effect="stamp" class="gold heavy">CERTIFIED</span>
| Attribute / Class | Values | Description |
data-effect="stamp" | — | Enables the stamp effect. Empty defaults to red ink. |
class="red", "blue", "green", "black", "gold" | — | Ink color preset. |
class="straight" | — | No rotation (0deg). |
class="slight" | — | Slight rotation (-2deg). |
class="heavy" | — | Heavy rotation (-8deg). |
| CSS Property | Default | Description |
--vb-stamp-color | Per preset | Ink color in OKLCH. |
data-effect="starburst" kawaii
Animated pastel starburst gradient background with rotating 10-degree conic-gradient rays and soft radial bokeh at the bottom.
<section data-effect="starburst"> <h2>Pastel Starburst</h2> <p>Animated rotating ray background.</p></section>
| Attribute / Class | Values | Description |
data-effect="starburst" | — | Enables the animated starburst background. |
data-effect="text-3d" core
Bold text with layered drop-shadows creating a 3D extrusion effect. Sets font-weight: 900.
<h1 data-effect="text-3d">3D Text</h1><h2 data-effect="text-3d" class="gold">Gold Extrusion</h2><h1 data-effect="text-3d" class="red animate">Animated</h1>
| Attribute / Class | Values | Description |
data-effect="text-3d" | — | Enables the 3D extrusion effect. |
class="red", "gold", "green", "purple", "black" | — | Shadow color preset. |
class="deep" | — | Doubles shadow angle to 2px for deeper extrusion. |
class="animate" | — | Oscillates shadow direction over 3 seconds. |
| CSS Property | Default | Description |
--vb-3d-color | Per preset | Extrusion color in OKLCH. |
--vb-3d-angle | 1px | Shadow offset per layer. |
data-effect="typewriter" effects
Classic character-by-character typing with optional blinking cursor and looping. Triggers when scrolled into view.
<h1 data-effect="typewriter" data-trigger="scroll">Hello, World!</h1><p data-effect="typewriter" data-trigger="scroll" style="--vb-typewriter-speed: 80ms; --vb-typewriter-delay: 500ms">This text types out more slowly after a brief pause.</p><h2 data-effect="typewriter" data-trigger="scroll" class="loop">Loops forever</h2><h2 data-effect="typewriter" data-trigger="scroll" class="no-cursor">No blinking cursor here</h2>
| Attribute / Class | Values | Description |
data-effect="typewriter" | — | Enables the typewriter effect. Use with data-trigger="scroll". |
class="loop" | — | Loop the typing animation. |
class="no-cursor" | — | Hide the blinking cursor. |
| CSS Property | Default | Description |
--vb-typewriter-speed | 50ms | Typing speed per character. |
--vb-typewriter-delay | 0ms | Initial delay before typing starts. |
data-effect="wiggle" kawaii
Playful left-right rotation wobble. Runs continuously by default, or only on hover.
<span data-effect="wiggle">Always wiggling</span><button data-effect="wiggle" data-trigger="hover">Wiggle on hover</button>
| Attribute / Class | Values | Description |
data-effect="wiggle" | — | Enables the wiggle effect (continuous by default). |
data-trigger="hover" | — | Wiggle only on hover. |
data-effect="ticker" effects
Animated number count-up on <data> elements. Counts from a start value to the element's value attribute using easeOutExpo easing — fast start, decelerating finish. Pairs with data-format-number for locale-aware formatting during animation.
<data value="50000" data-effect="ticker" data-trigger="scroll" style="--vb-ticker-duration: 2000">50,000</data>
Attributes
| Attribute | Values | Description |
data-effect="ticker" | — | Enables animated count-up. Use on <data> elements with a value attribute. |
data-trigger="scroll" | — | Start animation when scrolled into view (IntersectionObserver, 10% threshold). |
data-format-number | currency, percent, compact | Apply Intl.NumberFormat to intermediate values during animation. |
data-currency | e.g. USD, EUR | Currency code when using data-format-number="currency". |
data-locale | e.g. de-DE | Override locale for this element (defaults to html[lang]). |
CSS Properties
| CSS Property | Default | Description |
--vb-ticker-duration | 1000 | Animation duration in ms. |
--vb-ticker-start | 0 | Starting number for count-up. |
--vb-ticker-decimals | auto | Decimal places (auto-detected from value if omitted). |
How It Works
- The
scroll trigger watches for the element to enter the viewport (10% threshold)
- A
requestAnimationFrame loop animates from start to end value at 60fps
- Each frame applies
easeOutExpo easing for a fast-start, decelerating finish
- Intermediate values are formatted with
Intl.NumberFormat matching any data-format-number options
- At completion, sets
data-format-number-init to prevent double-formatting
With Format Number
Combine with data-format-number for locale-aware formatting during the animation:
<data value="48200" data-effect="ticker" data-trigger="scroll" data-format-number="currency" data-currency="USD" style="--vb-ticker-duration: 2000">$48,200</data> <data value="1500000" data-effect="ticker" data-trigger="scroll" data-format-number="compact" style="--vb-ticker-duration: 2500">1.5M</data>
Stats Pattern
The ticker pairs naturally with the Stats pattern:
<layout-grid data-layout-gap="m" style="--layout-grid-min: 10rem;"> <article> <data value="24521" data-effect="ticker" data-trigger="scroll" data-format-number>24,521</data> <p>Active Users</p> </article> <article> <data value="48200" data-effect="ticker" data-trigger="scroll" data-format-number="currency" data-currency="USD" style="--vb-ticker-duration: 2000">$48,200</data> <p>Revenue</p> </article></layout-grid>
Reduced Motion
The ticker checks prefers-reduced-motion: reduce and :root[data-motion-reduced]. When either is true, the animation is skipped entirely — the original text content is preserved as-is. data-format-number still formats normally.
Easing
function easeOutExpo(t) { return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);}
See also: data element for byte formatting and locale overrides.
Shared Behavior
Progressive Enhancement
All effects are progressive enhancements. Text is fully readable without JavaScript. CSS-only effects need no JS at all. Effects without a pack badge are in core.
Reduced Motion
All effects respect prefers-reduced-motion: reduce and :root[data-motion-reduced]. When reduced motion is active, text displays immediately with no animation.
Screen Readers
JS effects that split text into spans set aria-label on the host element so screen readers announce the full text naturally.
Scroll Trigger
Effects with data-trigger="scroll" use IntersectionObserver with threshold: 0.1 to trigger when scrolled into view. Effects play once (except data-effect="typewriter" with class="loop").
Dynamic Elements
A MutationObserver watches for dynamically added elements, so effects work with client-side rendering and lazy loading.
CSS Layer
Core effects use @layer web-components. Pack effects use @layer bundle-effects.
Accessibility
aria-label preserves full text for screen readers
prefers-reduced-motion respected by all effects
- CSS-only effects degrade gracefully in older browsers via
@supports
- No content is hidden permanently — text is always accessible
- Guard attributes (
data-*-init) prevent double initialization