All skills
simota avatar

/flow

@e307415
by shingo imotasimota/agent-skills85 stars
15

Implementing CSS/JS animations for hover effects, loading states, modal transitions, and gesture interactions. Use for meaningful motion, interaction feedback, or performance-safe animation.

Use this Skill: https://skilld.dev/gh/simota/agent-skills/flow

This session only. Nothing lands on disk.

referencemodern-css-animations.md

≈2.5k tokens on demand. Your agent reads this file only when SKILL.md points to it.

Modern CSS Animations

Purpose: Use this file when modern platform APIs can replace JavaScript or simplify animation architecture.

Contents

  • View Transitions API
  • @starting-style
  • Scroll-driven animations
  • Scroll-triggered animations (Chrome 145+)
  • @property
  • Progressive enhancement rules

Feature support matrix: see "Updated Feature Gate Table" below (precise browser versions). Native platform motion defaults (Material 3 Expressive, Liquid Glass) are covered in reference/spring-physics.md.

Progressive Enhancement Rules

  • Use @supports to gate modern features.
  • Provide a CSS-only baseline before adding advanced behavior.
  • Prefer View Transitions for context-preserving route changes, not every navigation.
  • Avoid scroll-driven animation for essential content visibility.

Minimal Examples

document.startViewTransition(() => {
  updateDOM();
});
::view-transition-old(root) {
  animation: fade-out 200ms ease-in;
}
::view-transition-new(root) {
  animation: fade-in 200ms ease-out;
}

dialog[open] {
  opacity: 1;
  transform: scale(1);
  transition: opacity 200ms ease-out, transform 200ms ease-out;

  @starting-style {
    opacity: 0;
    transform: scale(0.95);
  }
}

.reveal {
  opacity: 1;
  transform: none;
}

@supports (animation-timeline: view()) {
  .reveal {
    animation: fadeIn linear both;
    animation-timeline: view();
    animation-range: entry 0% entry 100%;
  }
}

When Not To Use

  • Do not require View Transitions on unsupported browsers.
  • Do not use scroll-driven motion for key affordances.
  • Do not use @property when a standard property animation is enough.

View Transitions Level 2 (MPA Cross-Document)

Cross-document View Transitions enable page transitions without JavaScript in MPAs. Chrome 126+, Safari 18.2+. Firefox not yet supported.

Basic MPA Transition

/* Add to both source and destination pages */
@view-transition {
  navigation: auto;
}

/* Custom slide animation */
@keyframes slide-in-from-right {
  from { transform: translateX(100%); }
}
@keyframes slide-out-to-left {
  to { transform: translateX(-100%); }
}

::view-transition-new(root) {
  animation: slide-in-from-right 300ms ease-out;
}
::view-transition-old(root) {
  animation: slide-out-to-left 300ms ease-in;
}

Shared Element Transition (MPA)

/* Source page */
.hero-image {
  view-transition-name: hero-image;
}

/* Destination page — same view-transition-name */
.detail-image {
  view-transition-name: hero-image;
}

@starting-style + transition-behavior

Pure CSS entry/exit animations for dialog and popover. Baseline achieved across all major browsers.

Dialog Entry/Exit

dialog {
  opacity: 0;
  transform: scale(0.95) translateY(8px);
  transition: opacity 200ms ease-out,
              transform 200ms ease-out,
              display 200ms allow-discrete,
              overlay 200ms allow-discrete;

  @starting-style {
    opacity: 0;
    transform: scale(0.95) translateY(8px);
  }
}

dialog[open] {
  opacity: 1;
  transform: scale(1) translateY(0);
}

Popover Entry/Exit

[popover] {
  opacity: 0;
  transform: translateY(4px);
  transition: opacity 150ms ease-out,
              transform 150ms ease-out,
              display 150ms allow-discrete,
              overlay 150ms allow-discrete;

  @starting-style {
    opacity: 0;
    transform: translateY(4px);
  }
}

[popover]:popover-open {
  opacity: 1;
  transform: translateY(0);
}

Scroll-Driven Animations (Practical Examples)

Chrome 115+, Safari 26+ (with threaded execution on ProMotion displays). Firefox behind flag. Always wrap in @supports and provide reduced-motion fallback.

ViewTimeline: Reveal on Scroll

@media (prefers-reduced-motion: no-preference) {
  @supports (animation-timeline: view()) {
    .reveal {
      opacity: 0;
      animation: fadeUp linear both;
      animation-timeline: view();
      animation-range: entry 0% entry 60%;
    }
  }
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

ScrollTimeline: Progress Bar

@supports (animation-timeline: scroll()) {
  .progress-bar {
    transform-origin: left;
    animation: progress linear;
    animation-timeline: scroll(root block);
  }

  @keyframes progress {
    from { transform: scaleX(0); }
    to { transform: scaleX(1); }
  }
}

animation-range Keywords

Keyword Meaning
entry 0% entry 100% Element entering the scroll area
contain Element fully within the scroll area
exit 0% exit 100% Element leaving the scroll area

@property for Gradient Animation

@property --color-start {
  syntax: '<color>';
  initial-value: #6366f1;
  inherits: false;
}
@property --color-end {
  syntax: '<color>';
  initial-value: #8b5cf6;
  inherits: false;
}

.gradient-btn {
  background: linear-gradient(135deg, var(--color-start), var(--color-end));
  transition: --color-start 300ms ease-out, --color-end 300ms ease-out;
}

.gradient-btn:hover {
  --color-start: #4f46e5;
  --color-end: #7c3aed;
}

Container Scroll-State Queries

Detect scroll-related states (stuck, snapped, scrolled) via CSS container queries — no JS scroll listeners needed.

.sticky-header {
  container-type: scroll-state;
}

@container scroll-state(stuck: top) {
  .sticky-header {
    box-shadow: 0 2px 8px oklch(0 0 0 / 0.15);
    backdrop-filter: blur(8px);
  }
}

@container scroll-state(snapped: x) {
  .carousel-item { opacity: 1; }
}
  • Support: Chrome 133+, Edge 133+. Use @supports for progressive enhancement.
  • Use cases: Sticky header shadow, carousel snap indicators, "back to top" visibility.
  • Rule: Always provide a no-support fallback — JS IntersectionObserver or static styling.

Intrinsic Size Animation

Animate to/from height: auto natively — eliminates FLIP, ResizeObserver, and max-height hacks.

:root {
  interpolate-size: allow-keywords;
}

.accordion-body {
  height: 0;
  overflow: clip;
  transition: height 0.3s ease, opacity 0.3s ease;
}

.accordion[open] > .accordion-body {
  height: auto;
}
  • Support: Chrome 129+, Edge 129+. Not yet in Safari/Firefox.
  • calc-size(): For computed intrinsic values — calc-size(auto, size - 20px).
  • Fallback: Use max-height with generous value or grid-template-rows: 0fr / 1fr trick.
  • Rule: Prefer interpolate-size global opt-in over per-element calc-size().

CSS linear() Easing Function

Define complex easing curves (bounce, elastic, spring) in pure CSS — no JS libraries.

/* Bounce easing */
.bounce {
  transition: transform 0.6s linear(
    0, 0.004, 0.016, 0.035, 0.063, 0.098, 0.141, 0.191,
    0.25, 0.316, 0.391, 0.472, 0.562, 0.66, 0.765, 0.878,
    1, 0.916, 0.844, 0.784, 0.735, 0.699, 0.675, 0.663,
    0.663, 0.675, 0.699, 0.735, 0.784, 0.844, 0.916, 1
  );
}

/* Spring easing */
.spring {
  transition: transform 0.5s linear(
    0, 0.009, 0.035, 0.078, 0.141, 0.222, 0.324, 0.446,
    0.591, 0.757, 0.946, 1.069, 1.115, 1.097, 1.033,
    0.957, 0.9, 0.879, 0.899, 0.951, 1.009, 1.042, 1.032,
    0.999, 0.976, 0.98, 1.001, 1.007, 1
  );
}
  • Support: Baseline 2024 — all major browsers.
  • Tooling: Use CSS linear() generator tools to convert spring/bounce parameters.
  • Rule: Prefer linear() over JS-based easing for transitions; keep GSAP/Motion for orchestrated sequences.

Scroll-Triggered Animations (Chrome 145+)

Time-based animations that fire when crossing a scroll offset — unlike scroll-driven animations which scrub with scroll progress. Replaces many IntersectionObserver + element.classList.add() patterns with declarative CSS.

Basic Usage

@supports (animation-trigger: --reveal) {
  @scroll-trigger --reveal {
    trigger-scope: root;
    trigger-range: entry 0% entry 50%;
  }

  .card {
    animation: fadeUp 400ms ease-out both;
    animation-trigger: --reveal play-forwards;
  }
}

@keyframes fadeUp {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}

Key Differences from Scroll-Driven

Aspect Scroll-Driven Scroll-Triggered
Timeline Scroll position controls progress Time-based (plays at own pace)
Reversibility Reverses when scrolling back Configurable via play-backwards
Use case Progress bars, parallax Entrance reveals, count-ups
API animation-timeline: scroll()/view() animation-trigger + @scroll-trigger
  • Support: Chrome 145+ only. Use @supports (animation-trigger: ...) for progressive enhancement.
  • Fallback: IntersectionObserver + class toggle for unsupported browsers.
  • Rule: Prefer scroll-triggered for entrance animations; prefer scroll-driven for progress-linked motion.

Updated Feature Gate Table

Feature Use For Support
View Transitions Level 1 SPA transitions, shared elements Chrome 111+, Safari 18+, Firefox 133+ (Baseline)
View Transitions Level 2 MPA/cross-document transitions Chrome 126+, Safari 18.2+ (Firefox not supported)
@starting-style Entry from display:none, popover/dialog Chrome 117+, Safari 17.4+, Firefox 129+ (Baseline)
transition-behavior: allow-discrete Bidirectional display:none animation All major browsers (Baseline)
Scroll-driven animations Progress bars, reveal-on-scroll Chrome 115+, Safari 26+ (Firefox behind flag; @supports required)
Scroll-triggered animations Entrance reveals, time-based on scroll Chrome 145+ (@supports required)
Container Scroll-State Sticky shadow, snap indicators Chrome 133+ (@supports required)
interpolate-size Height:auto animation, accordion Chrome 129+ (progressive enhancement)
linear() easing Bounce, elastic, spring CSS-only All major browsers (Baseline 2024)
@property Animating custom properties, gradients Chrome 85+, Safari 15.4+ (Firefox not yet)

Source: SKILL.md on GitHub

No alerts13d5 checks · Risk SAFE
  • Gen Agent Trust Hub13d

    The skill is a specialized motion implementation assistant focused on CSS and JavaScript animations. It follows industry best practices for performance, accessibility, and modern web standards. No malicious patterns, obfuscation, or unauthorized data access were detected. All external references are to trusted development tools and documentation.

  • Socket13d

    No alerts

  • Snyk13d

    Risk: LOW · No issues

  • Runlayer6mo

    10 files scanned · No issues

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at e307415. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub 2 days ago.

Activeupdated 2 weeks ago

README badge

README badge for simota/agent-skills/flow