CSS Standard Animation on Modals: A Production-Ready Approach

Use CSS transitions on opacity and transform with custom easing tokens and prefers-reduced-motion gating for smooth, accessible modal animations that run off the main thread.

The Skills repository by Emil Kowalski provides a design-first framework for building UI motion through an opinionated, skill-driven system. For developers implementing CSS standard animation on modals, the repository offers battle-tested recipes that prioritize performance, accessibility, and visual consistency across components.

How the Animate Skill Structures Modal Animations

Modal animations in the Skills framework live within the animate skill, located at skills/animate/SKILL.md. This file establishes a strict decision-making process for all UI motion: whether to animate, the purpose behind the animation, tool selection, property choices, easing definitions, duration constraints, interruption handling, and reduced-motion gating.

For standard modals, the skill mandates CSS transitions over keyframe animations. Transitions run on the compositor thread, eliminating main-thread jank during heavy page loads. The recommended properties—opacity and transform—are the only two CSS properties guaranteed to avoid layout recalculation or paint operations.

The Modal Animation Recipe

The implementation details reside in skills/animate/RECIPES.md, which contains copy-ready CSS for common components. Here is the exact modal pattern defined in that file:

/* Modal component */
.modal {
  /* Modals are centered, so we use a neutral transform-origin */
  transform-origin: center; 
  transition:
    opacity 250ms var(--ease-out),
    transform 250ms var(--ease-out);
}

/* Starting / ending states supplied by the skill */
.modal[data-starting-style],
.modal[data-ending-style] {
  opacity: 0;
  transform: scale(0.96);
}

/* Backdrop fades in sync with the modal */
.backdrop {
  transition: opacity 250ms var(--ease-out);
}

/* Reduced-motion fallback */
@media (prefers-reduced-motion: reduce) {
  .modal,
  .backdrop {
    transition: opacity 100ms ease;
    transform: none;
  }
}

Design Tokens and Easing

The custom property --ease-out is defined in skills/animate/SKILL.md alongside other motion tokens like --ease-in-out and --ease-drawer. These tokens ensure identical easing curves across all animated components, maintaining a cohesive visual language without developers manually copying cubic-bezier values.

The --ease-out curve translates to cubic-bezier(0.23, 1, 0.32, 1)—an ease-out-quint that delivers snappy, natural deceleration.

Accessibility and Device Adaptation

The Skills framework enforces reduced-motion gating at the skill level. Beyond the prefers-reduced-motion media query shown above, the system also considers input modality. As documented in the skill files, touch-only devices should skip transform animations that provide no functional benefit:

@media (hover: hover) and (pointer: fine) {
  .element:hover { transform: scale(1.05); }
}

When prefers-reduced-motion: reduce is active, the modal transitions to opacity-only with a shortened 100ms duration and zero transform overhead. This preserves contextual awareness without triggering vestibular discomfort.

JavaScript Fallback with Web Animations API

For cases where declarative CSS transitions are insufficient—such as dynamically injected modals or complex sequencing—skills/animate/RECIPES.md provides a Web Animations API equivalent:

element.animate(
  [
    { opacity: 0, transform: 'scale(0.96)' },
    { opacity: 1, transform: 'scale(1)' }
  ],
  {
    duration: 250,
    easing: 'cubic-bezier(0.23, 1, 0.32, 1)', /* matches --ease-out */
    fill: 'forwards'
  }
);

This JavaScript approach mirrors the CSS token values exactly, ensuring identical perceived motion regardless of implementation path.

How the Skills System Enforces Quality

The repository's architecture connects multiple skills into a verification chain:

By adhering to the CSS standard animation on modals pattern from RECIPES.md, developers automatically satisfy the review rules without additional validation steps.

Performance Characteristics

The modal animation recipe achieves optimal rendering performance through specific technical choices:

  • Compositor-only properties — opacity and transform never trigger layout or paint
  • 250ms duration — Fast enough to feel responsive, slow enough to perceive directionality
  • Ease-out easing — Natural deceleration that feels physically plausible
  • Scale(0.96) start state — Subtle enough to avoid jarring size jumps, noticeable enough to communicate emergence

These constraints emerge from the skill's decision tables, which weigh motion purpose against visual budget and cognitive load.

Summary

  • CSS transitions on opacity and transform provide the foundation for standard modal animations in the Skills framework
  • Custom easing tokens (--ease-out, etc.) defined in skills/animate/SKILL.md guarantee consistency across components
  • [data-starting-style] and [data-ending-style] attributes manage enter/exit states without JavaScript animation libraries
  • prefers-reduced-motion and input media queries gate motion appropriately for accessibility and device context
  • skills/animate/RECIPES.md contains production-ready code that satisfies skills/review-animations/SKILL.md requirements automatically

Frequently Asked Questions

What makes this modal pattern "standard" in the Skills framework?

The pattern is standard because it follows the animate skill's mandatory decision sequence: it uses CSS transitions (not keyframes), targets compositor-only properties, applies token-defined easing, and includes reduced-motion fallbacks. Any deviation requires justification against the review rules in skills/review-animations/SKILL.md.

Why scale to 0.96 instead of 0.9 or smaller?

The 0.96 scale value represents a minimal meaningful difference—large enough to signal emergence, small enough to avoid distraction. According to the skill's visual budget principles, modals should feel present without demanding attention. The 4% reduction matches similar patterns for drawers and dialogs throughout skills/animate/RECIPES.md.

Can I use this pattern with React or other frameworks?

Yes. The CSS pattern is framework-agnostic. The [data-starting-style] and [data-ending-style] attributes can be toggled by any framework's state management. For React specifically, you might apply these attributes during useLayoutEffect or use the Web Animations API fallback for more complex orchestration.

Where does the cubic-bezier value come from?

The cubic-bezier(0.23, 1, 0.32, 1) value is the concrete definition of the --ease-out token specified in skills/animate/SKILL.md. This curve provides a dramatic ease-out that feels snappier than standard CSS ease-out while remaining physically believable.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →