CSS Example: Button Press with Custom Easing in emilkowalski/skills

Use transform: scale(0.97) combined with a custom cubic-bezier(0.77, 0, 0.175, 1) easing curve to create tactile, responsive button press animations.

The skills repository by Emil Kowalski treats UI motion as a first-class design concern. This CSS example demonstrates how to implement a polished button press using the repository's layered architecture of design tokens, recipes, and standards—replacing weak built-in easings with deliberate, custom curves.

Architecture of Button Press Handling

The repository organizes animation guidance across focused modules that work together:

  • review-animations/STANDARDS.md – Defines baseline CSS patterns for interactive states, including a deliberately slow 2-second linear overlay transition for a "thoughtful" press feel. [Line 107]

  • animate/RECIPES.md – Provides ready-to-copy implementation recipes, including the minimal .button:active rule and overlay clip-path approach. [Lines 18, 207, 212]

  • emil-design-eng/SKILL.md – Enforces easing and duration tokens with custom cubic-bezier curves that replace standard ease-in/ease-out. [Lines 208, 303, 417, 598]

  • apple-design/SKILL.md – Recommends reacting on :active (pointer-down) rather than waiting for click release. [Line 30]

Three-Layer System

  1. Token layer – Centralized design tokens for easing curves and durations
  2. Recipe layer – Reusable, implementation-ready snippets
  3. Standard layer – Opinionated defaults and quality guidelines

Why Custom Easing Matters

Built-in CSS easings are explicitly deemed "too weak" for deliberate UI motion in STANDARDS.md. The repository advocates for strong cubic-bezier curves that provide quick acceleration followed by smooth settlement.

Recommended curve from emil‑design‑eng/SKILL.md: cubic-bezier(0.77, 0, 0.175, 1)

These curves live as design tokens, ensuring every component shares consistent motion language.

Complete CSS Example

This self-contained snippet follows the repository's guidance with three essential ingredients: scale-on-press feedback, overlay clip-path animation, and sub-300ms durations.

/* -------------------------------------------------------------
   Core button – uses the repo's "scale on press" token
   ------------------------------------------------------------- */
.button {
  position: relative;               /* required for overlay positioning */
  display: inline-block;
  padding: 0.5rem 1rem;
  background: #0069ed;
  color: #fff;
  border-radius: 0.25rem;
  cursor: pointer;
  /* Repository-wide default easing token */
  transition: transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}

/* -------------------------------------------------------------
   Press state – immediate tactile feedback on pointer-down
   ------------------------------------------------------------- */
.button:active {
  transform: scale(0.97);          /* tokenized "press-scale" value */
}

/* -------------------------------------------------------------
   Optional overlay – visual "fill" with custom easing
   ------------------------------------------------------------- */
.button .overlay {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.1);
  /* Start fully clipped on right side */
  clip-path: inset(0 100% 0 0);
  /* Custom strong easing from token list */
  transition: clip-path 0.25s cubic-bezier(0.77, 0, 0.175, 1);
}

/* Reveal overlay when button is pressed */
.button:active .overlay {
  clip-path: inset(0 0 0 0);
}

Mapping to Repository Sources

Implementation Detail Source File
transform transition with cubic-bezier animate/RECIPES.md – custom easing for UI actions
Baseline slow overlay (2s linear) review-animations/STANDARDS.md [L107]
Custom curve cubic-bezier(0.77,0,0.175,1) emil-design-eng/SKILL.md – "critical: use custom easing curves" [L108-123]
:active for pointer-down response apple-design/SKILL.md [L30]

Replace token values with your project's CSS variables (e.g., var(--duration-quick), var(--easing-strong)) for production use.

Key Source Files

File Contents Link
skills/review-animations/STANDARDS.md Canonical CSS patterns for interaction states View
skills/animate/RECIPES.md Ready-to-copy component recipes View
skills/emil-design-eng/SKILL.md Design token definitions and rationale View
skills/apple-design/SKILL.md Platform UX notes including :active behavior View
skills/animate/SKILL.md Animation system overview View

Summary

  • Scale transform (0.97) provides immediate tactile confirmation on :active
  • Custom cubic-bezier curves replace weak built-in easings for deliberate, quality motion
  • Clip-path overlay adds visual depth when extended with the repository's 2s baseline pattern
  • Pointer-down response on :active beats click-delayed feedback for perceived responsiveness

Frequently Asked Questions

What makes a cubic-bezier curve "strong" for button animations?

A strong curve has pronounced acceleration and deceleration phases. The repository's recommended cubic-bezier(0.77, 0, 0.175, 1) starts fast (0.77 x-velocity) and settles smoothly, creating responsive yet polished motion. Weak curves like ease-in-out distribute acceleration too evenly, feeling sluggish or unremarkable.

Why react on :active instead of JavaScript click handlers?

apple-design/SKILL.md emphasizes that :active triggers on pointer-down, providing immediate visual feedback. Click handlers wait for pointer-up, introducing perceptible lag. The CSS-only approach also performs better and respects reduced-motion preferences through native media queries.

How do I adjust timing without breaking the repository's standards?

Maintain the sub-300ms budget for primary motion (scale, color shifts). The optional overlay effect in STANDARDS.md intentionally uses 2 seconds as a "slow, deliberate" exception—keep this separate from interactive feedback to avoid perceived unresponsiveness.

Can I use this with CSS-in-JS or Tailwind?

Absolutely. Map the repository's tokens to your system's variables: the cubic-bezier values become theme constants, durations become spacing-scale tokens, and the clip-path overlay becomes a reusable component variant. The architectural principles remain identical across implementation methods.

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 →