Animations (presets) vs Tailwind effects (className)

Short guide for authors and maintainers: two ways to add motion in PageHub, both valid; they solve different jobs. As of the unified Effects builder both live as rows under Design → Effects, but they still write to different places under…

Short guide for authors and maintainers: two ways to add motion in PageHub, both valid; they solve different jobs. As of the unified Effects builder both live as rows under Design → Effects, but they still write to different places under the hood.

Design → Effects → Animation row (backed by AnimationsInput)

  • Drives root.animation* (and related props) on the node, not the raw animate-* Tailwind list by default.
  • CSS mode: merges preset classes (animate-css-*, ph-hover-*, ph-anim-scroll, …), inline animation-* / duration overrides, scroll/load/hover triggers via the animation system.
  • Framer mode: uses motion props / presets from the same panel.
  • Use when you want orchestrated behavior: entrance presets, scroll-triggered reveals, coordinated hover packages, or Framer-based motion tied to the builder's animation model.

Design → Effects → Transition / Transform / Filter / Backdrop rows (backed by per-group field exports of EffectsClassInput)

  • Edits Tailwind utilities on className: transition-*, duration-*, ease-*, delay-*, transforms (scale-*, translate-*, rotate-*, skew-*, origin-*, will-change-*), filters (blur-*, brightness-*, contrast-*, grayscale-*, hue-rotate-*, invert-*, saturate-*, sepia-*), and the parallel backdrop-* family.
  • Use for stock Tailwind motion and styling: transition-colors, scale-* / translate-*, blur-*, combining with hover: / responsive prefixes in the raw class string when needed.
  • Same element can use both layers (e.g. preset entrance on root animation plus transition-opacity on className); avoid duplicating the same intent twice (two spinners, two competing transitions on one property).
  • Note: the standalone animate-* utility (animate-spin, animate-pulse, …) is no longer exposed as its own picker entry in the Effects section; reach for it via Class name if you need it explicitly.

Design → Effects → Scroll Effect row (Container only)

  • Drives props.scrollEffect (+ scrollDirection, scrollSpeed, scrollSnap, scrollTimelineRunway, scrollSmoothing) on a Container typed as section.
  • Pin-driven horizontal scroll and scroll-timeline panels — same UX as the legacy "Scroll Effect" section, just folded into the Effects builder.

Advanced → Class name

  • Escape hatch for any utility, variants (focus:, dark:, …), or keys not exposed as a row yet (e.g. raw animate-spin continuous animations).

Responsive + dark: in structured panels (not animation-specific)

Structured toolbar inputs (colors, spacing, layout, etc.) respect breakpoint chips and the moon (dark scope) next to them: writes go to md:dark:… when both apply. That is separate from the Effects row distinctions; it applies across Design / Layout / Advanced. For full variant rules, focus:, group-*, and anything outside the v1 stack, use Class name or see Tailwind coverage matrix (Variants row and Editor scope: dark: and breakpoints).

For AI / codegen

  • Prefer the Animation row when the spec matches PageHub presets (load, scroll, hover kits, Framer).
  • Prefer the Transition / Transform / Filter / Backdrop rows or className when the spec is purely Tailwind utility strings (including animate-pulse, duration-300, ease-out).

See also: Tailwind coverage matrix (motion row and changelog), Effects builder section in the popover pattern doc.