When to Use Custom cubic-bezier Easing Curves Instead of Built-in CSS Easings
Use custom cubic-bezier easing curves when built-in CSS easings feel too weak or sluggish for UI interactions, especially for enter/exit animations, motion-critical elements, and any component where perceived responsiveness matters.
The emilkowalski/skills repository establishes a clear animation philosophy: default CSS easings (ease, ease-in, ease-out, ease-in-out, linear) are mathematically shallow and produce underwhelming results at typical UI durations (100-300 ms). According to the animation standards in skills/review-animations/STANDARDS.md, you should reach for deliberately sharper custom curves in nearly all production UI work.
Why Built-in CSS Easings Fall Short
Built-in easings were designed for general-purpose web animations. In STANDARDS.md, the repository maintainers identify a critical flaw: these curves lack the acceleration intensity needed for modern interface motion. The document explicitly warns against ease-in for visible UI elements because "it starts slow, delaying the exact moment the user is watching"—making a 200 ms ease-out animation feel demonstrably faster than the same duration with ease-in.
The core problem is perceived responsiveness. When a dropdown, drawer, or modal enters the viewport, users judge the interface's speed during the first milliseconds of motion. Shallow curves waste this window with gentle acceleration.
The Recommended Easing Hierarchy
The repository provides a decision framework in STANDARDS.md L27-L30:
| Situation | Recommended Approach |
|---|---|
| Entering/exiting UI elements (dropdowns, drawers, toasts) | ease-out custom curve |
| Moving/morphing on-screen objects (sliders, progress indicators) | ease-in-out custom curve |
| Hover and color changes | Standard ease |
| Constant motion (marquees, spinners) | linear |
| All other UI animations | Default to ease-out custom curve |
Strong Custom Curves in Practice
The repository defines shared tokens that replace built-in easings with mathematically stronger alternatives. As noted in skills/review-animations/SKILL.md L27-L33, "Built-in CSS easings are too weak; use strong custom curves."
/* src/styles/tokens.css — shared easing vocabulary */
:root {
--ease-out: cubic-bezier(0.23, 1, 0.32, 1); /* strong deceleration */
--ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* symmetric motion */
--ease-drawer: cubic-bezier(0.32, 0.72, 0, 1); /* iOS-style spring */
}
These values are intentionally aggressive. The --ease-out curve reaches ~23% of its journey with nearly full velocity, creating an immediate sense of responsiveness that ease-out (cubic-bezier(0, 0, 0.58, 1)) cannot match.
Four Situations Demanding Custom cubic-bezier Curves
1. Pronounced Acceleration or Deceleration
When an element must feel snappy—like a dropdown that snaps open—custom curves deliver the velocity curve that built-in easings lack.
2. Motion Central to User Experience
Modal entries, drawer slide-ins, and toast appearances are performance-critical moments. The review-animations/SKILL.md specifically targets these for custom curve enforcement.
3. Design System Consistency
Shared tokens ensure every component speaks the same motion language. The skills/improve-animations/PLAN-TEMPLATE.md documents where these tokens live and how to extend them.
4. When Built-in Curves Feel "Flat"
The "responsive easing" rule in review-animations/SKILL.md mandates swapping ease-in for custom curves whenever the animated element is visible to the user.
Code Examples: Replacing Built-in with Custom
Basic Transition Comparison
/* Weak: built-in ease-out */
.fade-in-weak {
opacity: 0;
transition: opacity 200ms ease-out;
}
/* Strong: custom cubic-bezier */
.fade-in-strong {
opacity: 0;
transition: opacity 200ms cubic-bezier(0.23, 1, 0.32, 1);
}
Both animate for 200 ms. The custom curve starts faster, making the transition feel more immediate.
Drawer with iOS-Style Easing
.drawer {
transform: translateX(-100%);
transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);
}
.drawer.is-open {
transform: translateX(0);
}
This matches the --ease-drawer token, producing the characteristic "snap and settle" of native iOS drawers.
Web Animations API with Custom Curves
const element = document.querySelector('.modal');
element.animate(
[
{ transform: 'scale(0.95)', opacity: 0 },
{ transform: 'scale(1)', opacity: 1 }
],
{
duration: 250,
easing: 'cubic-bezier(0.23, 1, 0.32, 1)',
fill: 'forwards'
}
);
The same custom curve applies across CSS transitions, CSS animations, and JavaScript-driven WAAPI.
Performance Considerations
Custom cubic-bezier curves carry no runtime cost beyond built-in easings. The browser computes both identically. For performance-critical systems with massive animated lists, the visual benefit of stronger curves remains significant without measurable overhead.
The repository's stance is unequivocal: default to custom curves. Only hover states and constant motion warrant built-in alternatives.
Summary
- Never use
ease-infor visible UI elements—it delays the motion users are watching. - Default to strong
ease-outcustom curves for enter/exit animations. - Use symmetric
ease-in-outfor morphing and movement within the viewport. - Define shared tokens in
src/styles/tokens.cssto enforce consistency across components. - Reference specific values:
cubic-bezier(0.23, 1, 0.32, 1)for quick deceleration,cubic-bezier(0.32, 0.72, 0, 1)for drawer-style spring.
Frequently Asked Questions
What makes a custom cubic-bezier curve "stronger" than built-in easings?
A stronger curve has more pronounced derivatives—meaning acceleration and deceleration happen more aggressively. The repository's --ease-out (0.23, 1, 0.32, 1) reaches high velocity immediately, while CSS ease-out (0, 0, 0.58, 1) accelerates gradually. This mathematical difference translates to perceived speed at durations under 300 ms.
Can I use custom easing curves with JavaScript animation libraries?
Yes. Libraries like Framer Motion, GSAP, and React Spring all accept cubic-bezier values. The repository's skills/find-animation-opportunities/SKILL.md demonstrates extracting these exact values for use across any animation system.
Should I ever use built-in CSS easings in production?
The repository permits ease for subtle hover states and linear for constant motion. All other cases—particularly any animation the user actively watches—should use custom curves as defined in STANDARDS.md.
How do I audit my existing animations for weak easings?
The skills/review-animations/SKILL.md provides review checklists. Look for ease-in on visible elements, ease-out without custom values, and durations where built-in curves feel sluggish. Replace with the token set from src/styles/tokens.css.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →