# Why Ease-In Should Never Be Used for UI Interactions: Lessons from the emilkowalski/skills Repository

> Discover why ease-in animations hinder UI responsiveness. Learn from the emilkowalski/skills repository why ease-out is the superior choice for fluid user interfaces.

- Repository: [Emil Kowalski/skills](https://github.com/emilkowalski/skills)
- Tags: best-practices
- Published: 2026-07-29

---

**Ease-in should never be used for UI interactions because it starts slow and delays the exact moment the user is watching, making interfaces feel sluggish and unresponsive compared to ease-out alternatives.**

In the `emilkowalski/skills` repository, the author establishes strict animation standards that explicitly classify `ease-in` as a "finding"—a code smell that must be corrected during review. This open-source collection of design engineering skills documents why perceptual speed matters more than actual duration, and how the right easing curves can make a 200ms animation feel instantaneous while the wrong ones make it feel like lag.

## The Problem with Ease-In in User Interfaces

According to [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md) (line 28), the repository explicitly states: "**`ease-in` on UI is always a finding**—it starts slow, delaying the exact moment the user is watching." This architectural decision stems from a fundamental mismatch between the curve's mathematical behavior and user expectations.

When a user clicks a button or triggers a dropdown, they expect immediate visual feedback. An `ease-in` curve accelerates from zero velocity, meaning the animation remains nearly invisible for the first 30-40% of its duration. This creates a perceptual delay that makes the interface feel broken or underpowered, even when the total animation time is identical to faster-feeling alternatives.

## Perceptual Speed and User Expectations

The repository emphasizes that **perceptual speed** trumps actual duration. As documented in [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) (line 27), a 200ms `ease-out` transition *feels* significantly faster than a 200ms `ease-in` because the motion begins immediately at maximum velocity.

This phenomenon occurs because:
- **Ease-out** provides instant feedback that the system registered the interaction
- **Ease-in** forces the user to wait through "dead time" before meaningful motion occurs
- Users unconsciously judge responsiveness by the time to first visible movement, not total animation time

## Recommended Alternatives: Ease-Out and Custom Curves

The `emilkowalski/skills` codebase standardizes on **ease-out** for all entering and exiting animations, with specific cubic-bezier values defined as reusable CSS tokens.

### CSS Token Definitions

In [`skills/review-animations/STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/skills/review-animations/STANDARDS.md) (lines 32-33), the repository defines global easing tokens that embody the "strong ease-out" philosophy:

```css
:root {
  --ease-out: cubic-bezier(0.23, 1, 0.32, 1);   /* strong ease-out for UI */
  --ease-in-out: cubic-bezier(0.77, 0, 0.175, 1); /* movement across screen */
  --ease-drawer: cubic-bezier(0.32, 0.72, 0, 1);  /* specific for drawers */
}

```

These tokens ensure consistency across components while enforcing the "no ease-in" rule. New components must reference `--ease-out` rather than generic CSS keywords.

### Button Interactions

For button press feedback, the standards recommend a subtle scale-down with a fast ease-out transition to confirm the interaction without delay. From [`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md) (line 59):

```css
button:active {
  transform: scale(0.97);
  transition: transform 160ms var(--ease-out); /* 160ms feels snappy */
}

```

This pattern provides immediate tactile feedback, whereas an `ease-in` curve would make the button feel unresponsive during the critical first 50ms of the press.

### Dropdown Animations

Dropdowns represent the most common violation of this principle. As noted in [`skills/emil-design-eng/SKILL.md`](https://github.com/emilkowalski/skills/blob/main/skills/emil-design-eng/SKILL.md) (line 46), "`ease-in` on dropdown … feels sluggish; `ease-out` gives instant feedback." The corrected implementation from [`skills/improve-animations/PLAN-TEMPLATE.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/PLAN-TEMPLATE.md) (line 32) shows:

```css
.dropdown {
  transition: transform 200ms var(--ease-out),
              opacity 200ms var(--ease-out);
}

```

This ensures the menu appears to spring open immediately upon user action, rather than slowly gathering speed while the user waits.

## Code Review Standards

The repository treats animation auditing as a first-class quality gate. The [`skills/improve-animations/AUDIT.md`](https://github.com/emilkowalski/skills/blob/main/skills/improve-animations/AUDIT.md) file mandates that reviewers flag any UI component using `ease-in` and replace it with `ease-out` or a custom cubic-bezier.

Key guidelines from [`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md) (lines 21-24) specify:
- **Entering or exiting** → `ease-out` (starts fast, feels responsive)
- **Hover / color change** → `ease` (standard CSS ease)
- **Never** → `ease-in` for any user-triggered interaction

Toast notifications follow the same pattern, using `--ease-out` for a smooth, quick entry over 400ms ([`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md), line 83), ensuring error messages and confirmations appear instantly when the user needs them most.

## Summary

- **Ease-in delays feedback** by starting at zero velocity, breaking user expectations for immediate response.
- **Ease-out feels faster** than ease-in at identical durations because it provides instant initial movement.
- The `emilkowalski/skills` repository defines **CSS custom properties** like `--ease-out: cubic-bezier(0.23, 1, 0.32, 1)` to standardize strong ease-out curves.
- **Code reviews** explicitly flag ease-in on UI as a "finding" that must be replaced with ease-out or custom cubic-bezier curves.
- **Buttons, dropdowns, and toasts** should all use ease-out to maintain a consistent, responsive UI language.

## Frequently Asked Questions

### What makes ease-in feel slower than ease-out if they have the same duration?

Ease-in starts with zero velocity and accelerates, meaning the first half of the animation shows minimal visible change. Ease-out starts at maximum velocity and decelerates, so the user sees immediate displacement. As documented in the repository, users judge speed by time-to-first-movement, not total animation time, making ease-out feel responsive while ease-in feels delayed.

### When is it acceptable to use ease-in according to the emilkowalski/skills standards?

The repository treats ease-in as "always a finding" for UI interactions. However, `ease-in-out` (cubic-bezier(0.77, 0, 0.175, 1)) is acceptable for elements that travel long distances across the screen, as the initial ease-out provides feedback while the final ease-in prevents jarring stops. Pure ease-in should never appear in user-facing components.

### How do I migrate existing CSS from ease-in to the recommended patterns?

Replace `transition-timing-function: ease-in` with `var(--ease-out)` or `cubic-bezier(0.23, 1, 0.32, 1)`. For enter animations, ensure you use the `--ease-out` token defined in [`STANDARDS.md`](https://github.com/emilkowalski/skills/blob/main/STANDARDS.md). For micro-interactions like button presses, target 160ms duration with the strong ease-out curve to maintain consistency with the repository's design system.

### Does ease-in ever make sense for non-UI animations?

The repository focuses specifically on UI interactions where user expectation demands immediate feedback. While the standards don't explicitly address cinematic or decorative animations, the underlying principle remains: any animation where a user is waiting for completion should avoid ease-in to prevent perceived lag. Ease-in might suit objects falling under gravity in game physics, but not interface elements responding to clicks or hovers.