Utilities

Transitions & Animation

Create transition and animation utilities for smooth state changes and motion effects with full type safety.

Overview

Transition and animation utilities help you create smooth visual changes and motion effects. These utilities control which properties animate, how long animations take, and what easing functions to use.

Why Use Transition & Animation Utilities?

Transition and animation utilities help you:

  • Create smooth interactions: Add polish with animated hover and focus states
  • Control timing: Define consistent animation durations across your application
  • Apply easing functions: Use predefined timing functions for natural motion
  • Improve user experience: Guide attention with purposeful animations

useTransitionPropertyUtility

The useTransitionPropertyUtility() function creates utility classes for specifying which properties should animate.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useTransitionPropertyUtility } from "@styleframe/theme";

const s = styleframe();

useTransitionPropertyUtility(s, {
    none: 'none',
    all: 'all',
    default: 'color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter',
    colors: 'color, background-color, border-color, text-decoration-color, fill, stroke',
    opacity: 'opacity',
    shadow: 'box-shadow',
    transform: 'transform',
});

export default s;

useTransitionDurationUtility

The useTransitionDurationUtility() function creates utility classes for setting animation duration.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useTransitionDurationUtility } from "@styleframe/theme";

const s = styleframe();

useTransitionDurationUtility(s, {
    '0': '0s',
    '75': '75ms',
    '100': '100ms',
    '150': '150ms',
    '200': '200ms',
    '300': '300ms',
    '500': '500ms',
    '700': '700ms',
    '1000': '1000ms',
});

export default s;

useTransitionTimingFunctionUtility

The useTransitionTimingFunctionUtility() function creates utility classes for setting easing functions.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useTransitionTimingFunctionUtility } from "@styleframe/theme";

const s = styleframe();

useTransitionTimingFunctionUtility(s, {
    linear: 'linear',
    in: 'cubic-bezier(0.4, 0, 1, 1)',
    out: 'cubic-bezier(0, 0, 0.2, 1)',
    'in-out': 'cubic-bezier(0.4, 0, 0.2, 1)',
});

export default s;

Easing Functions

ValueDescription
linearConstant speed throughout
inStarts slow, accelerates (ease-in)
outStarts fast, decelerates (ease-out)
in-outSlow start and end (ease-in-out)

useTransitionDelayUtility

The useTransitionDelayUtility() function creates utility classes for delaying transitions.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useTransitionDelayUtility } from "@styleframe/theme";

const s = styleframe();

useTransitionDelayUtility(s, {
    '0': '0s',
    '75': '75ms',
    '100': '100ms',
    '150': '150ms',
    '200': '200ms',
    '300': '300ms',
    '500': '500ms',
    '700': '700ms',
    '1000': '1000ms',
});

export default s;

useAnimationUtility

The useAnimationUtility() function creates utility classes for applying CSS animations.

styleframe.config.ts
import { styleframe } from "styleframe";
import { useAnimationUtility } from "@styleframe/theme";

const s = styleframe();
const { keyframes } = s;

// Define keyframes
const spin = keyframes('spin', {
    'from': { transform: 'rotate(0deg)' },
    'to': { transform: 'rotate(360deg)' },
});

const ping = keyframes('ping', {
    '75%, 100%': { transform: 'scale(2)', opacity: '0' },
});

const pulse = keyframes('pulse', {
    '0%, 100%': { opacity: '1' },
    '50%': { opacity: '.5' },
});

const bounce = keyframes('bounce', {
    '0%, 100%': { transform: 'translateY(-25%)', animationTimingFunction: 'cubic-bezier(0.8, 0, 1, 1)' },
    '50%': { transform: 'translateY(0)', animationTimingFunction: 'cubic-bezier(0, 0, 0.2, 1)' },
});

useAnimationUtility(s, {
    none: 'none',
    spin: `${spin.name} 1s linear infinite`,
    ping: `${ping.name} 1s cubic-bezier(0, 0, 0.2, 1) infinite`,
    pulse: `${pulse.name} 2s cubic-bezier(0.4, 0, 0.6, 1) infinite`,
    bounce: `${bounce.name} 1s infinite`,
});

export default s;

Examples

Hover Transition

styleframe.config.ts
import { styleframe } from "styleframe";
import { useTransitionPropertyUtility, useTransitionDurationUtility } from "@styleframe/theme";
import { useBackgroundColorUtility } from "@styleframe/theme";

const s = styleframe();
const { modifier } = s;

const hover = modifier('hover', ({ declarations }) => ({
    '&:hover': declarations,
}));

useTransitionPropertyUtility(s, {
    colors: 'color, background-color, border-color',
});

useTransitionDurationUtility(s, {
    '200': '200ms',
});

useBackgroundColorUtility(s, {
    gray: '#f3f4f6',
    primary: '#006cff',
});

useBackgroundColorUtility(s, { primary: '#006cff' }, [hover]);

export default s;

Usage in HTML:

<button class="_bg:gray _hover:bg:primary _transition:colors _transition-duration:200">
    Hover me
</button>

Loading Spinner

styleframe.config.ts
import { styleframe } from "styleframe";
import { useAnimationUtility } from "@styleframe/theme";

const s = styleframe();
const { keyframes } = s;

const spin = keyframes('spin', {
    'from': { transform: 'rotate(0deg)' },
    'to': { transform: 'rotate(360deg)' },
});

useAnimationUtility(s, {
    spin: `${spin.name} 1s linear infinite`,
});

export default s;

Usage in HTML:

<svg class="_animation:spin" width="24" height="24">
    <circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4" fill="none" />
</svg>

Best Practices

  • Use purposeful animation: Animations should enhance UX, not distract
  • Respect reduced motion: Consider users who prefer reduced motion
  • Keep durations short: Most UI transitions should be 150-300ms
  • Use appropriate easing: Ease-out for entering, ease-in for leaving
  • Avoid animating layout: Prefer transform and opacity for performance
  • Be consistent: Use the same timing across similar interactions

FAQ