
Make Interfaces Feel Better
Apply interruptible motion, split-and-stagger enter transitions, and contextual icon animation rules so interactive UI feels responsive instead of janky.
Overview
make-interfaces-feel-better is an agent skill most often used in Build (also Ship review) that teaches interruptible CSS motion and staggered enter animations for polished interfaces.
Install
npx skills add https://github.com/jakubkrehel/make-interfaces-feel-better --skill make-interfaces-feel-betterWhat is this skill?
- Hard rule: CSS transitions for interactive open/close; keyframes reserved for one-shot sequences
- Comparison table: transitions are interruptible and retarget; keyframe animations restart on state change
- Enter animations: split content into semantic chunks then stagger instead of animating one large container
- Drawer example shows mid-animation reversal without snap or restart
- Covers contextual icon animations alongside enter/exit transitions
- CSS transitions vs keyframes comparison table with 4 contrast rows
- 3-step enter animation workflow: split, stagger, per-group motion
Adoption & trust: 28.1k installs on skills.sh; 953 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
Your UI state changes stutter or snap because animations restart when users interrupt hovers, toggles, or drawers mid-motion.
Who is it for?
Solo frontend builders polishing SaaS panels, modals, and navigation with CSS who care about perceived performance and quality.
Skip if: Teams needing full motion-design systems in After Effects, game engine timelines, or backend-only services with no UI layer.
When should I use this skill?
Interactive UI motion feels janky, non-interruptible, or enter transitions animate entire containers instead of semantic chunks.
What do I get? / Deliverables
You ship transition-driven interactive motion, staged enter animations on semantic chunks, and icon feedback that stays smooth under rapid user input.
- Updated CSS using transitions for interactive state changes
- Staggered enter animation structure split by semantic UI groups
Recommended Skills
Journey fit
Spans multiple journey phases - primary shelf plus alternate fits below.
Motion polish is applied while crafting UI components—the first place builders feel quality gaps—though the same rules matter during pre-ship UI review. Guidance targets CSS transitions, keyframes discipline, and enter animations on interface elements, which maps directly to frontend implementation.
Where it fits
Replace keyframe drawer slides with translateX transitions so rapid open/close does not restart the timeline.
Stagger hero copy and CTA entrance on a landing prototype so investor demos feel finished, not wireframe-flat.
Audit interactive panels for keyframes on toggles and fix before release checklist sign-off.
How it compares
Opinionated CSS motion playbook for product UI, not a component library or automated Lighthouse perf audit.
Common Questions / FAQ
Who is make-interfaces-feel-better for?
Indie developers and designer-developers implementing web or extension UIs who want concrete CSS rules for motion that survives real user interruption.
When should I use make-interfaces-feel-better?
During Build while coding drawers, toggles, and page enters; in Validate when a prototype demo must feel credible; and in Ship review before launch when modal and onboarding motion is still stiff.
Is make-interfaces-feel-better safe to install?
It is documentation-only CSS guidance with no shell or network requirements—review the Security Audits panel on this page for the skill package itself.
SKILL.md
READMESKILL.md - Make Interfaces Feel Better
# Animations Interruptible animations, enter/exit transitions, and contextual icon animations. ## Interruptible Animations Users change intent mid-interaction. If animations aren't interruptible, the interface feels broken. ### CSS Transitions vs. Keyframes | | CSS Transitions | CSS Keyframe Animations | | --- | --- | --- | | **Behavior** | Interpolate toward latest state | Run on a fixed timeline | | **Interruptible** | Yes — retargets mid-animation | No — restarts from beginning | | **Use for** | Interactive state changes (hover, toggle, open/close) | Staged sequences that run once (enter animations, loading) | | **Duration** | Adapts to remaining distance | Fixed regardless of state | ```css /* Good — interruptible transition for a toggle */ .drawer { transform: translateX(-100%); transition: transform 200ms ease-out; } .drawer.open { transform: translateX(0); } /* Clicking again mid-animation smoothly reverses — no jank */ ``` ```css /* Bad — keyframe animation for interactive element */ .drawer.open { animation: slideIn 200ms ease-out forwards; } /* Closing mid-animation snaps or restarts — feels broken */ ``` **Rule:** Always prefer CSS transitions for interactive elements. Reserve keyframes for one-shot sequences. ## Enter Animations: Split and Stagger Don't animate a single large container. Break content into semantic chunks and animate each individually. ### Step by Step 1. **Split** into logical groups (title, description, buttons) 2. **Stagger** with ~100ms delay between groups 3. **For titles**, consider splitting into individual words with ~80ms stagger 4. **Combine** `opacity`, `blur`, and `translateY` for the enter effect ### Code Example ```tsx // Motion (Framer Motion) — staggered enter function PageHeader() { return ( <motion.div initial="hidden" animate="visible" variants={{ visible: { transition: { staggerChildren: 0.1 } }, }} > <motion.h1 variants={{ hidden: { opacity: 0, y: 12, filter: "blur(4px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)" }, }} > Welcome </motion.h1> <motion.p variants={{ hidden: { opacity: 0, y: 12, filter: "blur(4px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)" }, }} > A description of the page. </motion.p> <motion.div variants={{ hidden: { opacity: 0, y: 12, filter: "blur(4px)" }, visible: { opacity: 1, y: 0, filter: "blur(0px)" }, }} > <Button>Get started</Button> </motion.div> </motion.div> ); } ``` ### CSS-Only Stagger ```css .stagger-item { opacity: 0; transform: translateY(12px); filter: blur(4px); animation: fadeInUp 400ms ease-out forwards; } .stagger-item:nth-child(1) { animation-delay: 0ms; } .stagger-item:nth-child(2) { animation-delay: 100ms; } .stagger-item:nth-child(3) { animation-delay: 200ms; } @keyframes fadeInUp { to { opacity: 1; transform: translateY(0); filter: blur(0); } } ``` ## Exit Animations Exit animations should be softer and less attention-grabbing than enter animations. The user's focus is moving to the next thing — don't fight for attention. ### Subtle Exit (Recommended) ```tsx // Small fixed translateY — indicates direction without drama <motion.div exit={{ opacity: 0, y: -12, filter: "blur(4px)", transition: { duration: 0.15, ease: "easeIn" }, }} > {content} </motion.div> ``` ### Full Exit (When Context Matters) ```tsx // Slide fully out — use when spatial context is important // (e.g., a card returning to a list, a drawer closing) <motion.div exit={{ opacity: 0, x: "-100%", transition: { duration: 0.2, ease: "easeIn" }, }} > {content} </motion.div> ``` ### Good vs. Bad ```css /* Good — subtle exit */ .item-exit { opacity: 0; transform: translateY(-12px); transition: opacity 150ms ease-in, transform 1