Skip to content

Motion

helixui ships a small motion system: a few duration tokens, a few easing tokens, and a set of CSS utility classes that compose them. Components reference the tokens directly, so retuning a theme retunes every animation in one place.

Duration tokens

TokenValueWhen to use
motion.duration.instant0msSuppress motion (low-power or reduced-motion contexts).
motion.duration.fast120msHover, press, focus ring, tooltip.
motion.duration.normal180msDefault UI transitions, popovers, toasts.
motion.duration.slow240msSheets, dialogs, drawers entering.
motion.duration.slower320msLong collapsing sections, page transitions.

CSS variables: --helixui-motion-duration-{instant,fast,normal,slow,slower}.

Easing tokens

TokenCurveWhen to use
motion.easing.linearlinearIndeterminate progress, spinners.
motion.easing.standardcubic-bezier(0.2, 0, 0, 1)Default UI ease — smooth start, slight settle.
motion.easing.emphasizedcubic-bezier(0.32, 0.72, 0, 1)Material-style emphasis. Sheets, toasts.
motion.easing.deceleratecubic-bezier(0, 0, 0.2, 1)Elements entering view.
motion.easing.acceleratecubic-bezier(0.4, 0, 1, 1)Elements exiting view.
motion.easing.springcubic-bezier(0.16, 1, 0.3, 1)Bouncy spring — entrance scale-ups, hover lifts.

CSS variables: --helixui-motion-easing-{linear,standard,emphasized,decelerate,accelerate,spring}.

Utility classes

Imported automatically with @helixui/core/styles.css.

Entrance animations (one-shot)

<div class="helixui-anim-fade-in"></div>
<div class="helixui-anim-slide-in-up"></div>
<div class="helixui-anim-slide-in-down"></div>
<div class="helixui-anim-slide-in-left"></div>
<div class="helixui-anim-slide-in-right"></div>
<div class="helixui-anim-scale-in"></div>

All use motion.duration.normal + motion.easing.decelerate (or spring for scale-in).

Looping states

<div class="helixui-anim-pulse"></div> <!-- attention or loading -->
<div class="helixui-anim-spin"></div> <!-- 0.9s linear, for spinners -->
<div class="helixui-anim-bounce"></div> <!-- soft vertical bounce -->
<div class="helixui-anim-shimmer"></div> <!-- skeleton-style sweep -->

Stagger children

Add helixui-anim-stagger to a parent to give the first 12 children incremental animation-delays. Combine with any helixui-anim-* class on each child.

<ul class="helixui-anim-stagger">
<li class="helixui-anim-slide-in-up">First</li>
<li class="helixui-anim-slide-in-up">Second</li>
<li class="helixui-anim-slide-in-up">Third</li>
</ul>

Interaction primitives

<button class="helixui-tap">Lift on hover, scale on press</button>
<a class="helixui-hover-lift">Lift on hover only</a>
<div class="helixui-press">Scale on press only</div>
<input class="helixui-focus-pulse" />

helixui-tap = helixui-hover-lift + helixui-press. Drop it onto any tappable surface (cards, tiles, custom buttons).

Reduced motion

helixui respects prefers-reduced-motion: reduce automatically. The motion stylesheet collapses every animation duration and transition duration to 0.01ms, so animations effectively snap to their end state but transitionend / animationend events still fire — useful for components that bind exit cleanup to those events.

You don’t need to add per-component reduced-motion guards.

Theming motion

Because all timings are CSS variables, a DNA theme can rebind motion at a scope:

[data-theme="dense"] {
--helixui-motion-duration-fast: 80ms;
--helixui-motion-duration-normal: 120ms;
}

Every component inside [data-theme="dense"] becomes snappier without code changes.