Loading...
Loading...
Production-ready CSS transitions for web apps. Use when implementing notification badges, dropdowns, modals, panel reveals, page transitions, card resizes, number pop-ins, text swaps, or icon swaps. Triggers on "add a transition", "animate the dropdown", "make the modal open smoothly", "swap icon", "page slide", "stagger animation", "open / close transition", "make it animate", "tween the size", "fade between", "smooth open", "smooth close".
npx skill4agent add jakubantalik/transitions-dev transitions-devt-*prefers-reduced-motion| Transition | When to use | Reference |
|---|---|---|
| Card resize | Tween a container's width or height when its layout state changes. | 01-card-resize.md |
| Number pop-in | Re-enter each digit with a blurred slide when a number updates. | 02-number-pop-in.md |
| Notification badge | Slide a small badge onto a trigger and pop the dot. | 03-notification-badge.md |
| Text states swap | Swap text in place with a blurred up-and-down transition. | 04-text-states-swap.md |
| Menu dropdown | Open an origin-aware dropdown that grows from its trigger. | 05-menu-dropdown.md |
| Modal open / close | Scale-up modal dialog with a softer scale-down on close. | 06-modal.md |
| Panel reveal | Slide a panel into a region with a cross-blur. | 07-panel-reveal.md |
| Page side-by-side | Slide between two side-by-side pages (list ↔ detail, step 1 ↔ step 2). | 08-page-side-by-side.md |
| Icon swap | Cross-fade two icons in the same slot with blur and scale. | 09-icon-swap.md |
:root/* transitions-dev — copy this :root block into your project once.
Every transition snippet reads from these semantic names. */
:root {
/* Card resize */
--resize-dur: 300ms;
--resize-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Number pop-in */
--digit-dur: 500ms;
--digit-distance: 8px;
--digit-stagger: 70ms;
--digit-blur: 2px;
--digit-ease: cubic-bezier(0.34, 1.45, 0.64, 1);
--digit-dir-x: 0;
--digit-dir-y: 1;
/* Notification badge */
--badge-slide-dur: 260ms;
--badge-pop-dur: 500ms;
--badge-pop-close-dur: 180ms;
--badge-fade-dur: 400ms;
--badge-fade-close-dur: 180ms;
--badge-blur: 2px;
--badge-offset-x: -8.2px;
--badge-offset-y: 12.4px;
--badge-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--badge-pop-ease: cubic-bezier(0.34, 1.36, 0.64, 1);
--badge-close-ease: cubic-bezier(0.4, 0, 0.2, 1);
/* Text states swap */
--text-swap-dur: 200ms;
--text-swap-translate-y: 8px;
--text-swap-blur: 2px;
--text-swap-ease: ease-out;
/* Menu dropdown */
--dropdown-open-dur: 250ms;
--dropdown-close-dur: 150ms;
--dropdown-pre-scale: 0.97;
--dropdown-closing-scale: 0.99;
--dropdown-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Modal open / close */
--modal-open-dur: 250ms;
--modal-close-dur: 150ms;
--modal-scale: 0.96;
--modal-scale-close: 0.96;
--modal-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Panel reveal */
--panel-open-dur: 400ms;
--panel-close-dur: 350ms;
--panel-translate-y: 100px;
--panel-blur: 2px;
--panel-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Page side-by-side */
--page-slide-dur: 200ms;
--page-fade-dur: 200ms;
--page-slide-distance: 8px;
--page-blur: 3px;
--page-stagger: 0ms;
--page-exit-enabled: 1;
--page-slide-ease: cubic-bezier(0.22, 1, 0.36, 1);
--page-fade-ease: cubic-bezier(0.22, 1, 0.36, 1);
/* Icon swap */
--icon-swap-dur: 200ms;
--icon-swap-blur: 2px;
--icon-swap-start-scale: 0.25;
--icon-swap-ease: ease-in-out;
}--pX-*--badge-*--dropdown-*--modal-*:rootwill-change.t-dropdown.t-modaldata-opendata-statedata-page.is-open.is-closing.is-exit.is-enter-start.is-animating@media (prefers-reduced-motion: reduce)getComputedStyle(...)getPropertyValue("--…"):rootsetTimeout.is-closingvoid el.offsetHeighttransition: …transition: all