Loading...
Loading...
Master microinteractions, animations, transitions, and feedback systems. Create intentional, delightful interactions that guide users and provide clear feedback. Includes animation principles, timing, easing, state transitions, and best practices for performance and accessibility.
npx skill4agent add sanky369/vibe-building-skills interaction-physicsTrigger: User hovers over button
Rules:
- Background color changes to darker shade
- Duration: 200ms
- Easing: ease-out
Feedback:
- Visual: background color transition
- Indicates: button is interactive
Loops & Modes:
- Repeats on every hover
- Can be interrupted by click or mouse leave/* UI Feedback - Fast */
button {
transition: background-color 200ms ease-out;
}
/* Transitions - Medium */
.modal {
transition: opacity 400ms ease-out, transform 400ms ease-out;
}
/* Loading - Slower */
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
.spinner {
animation: spin 1s linear infinite;
}| Easing | Meaning | Use Case |
|---|---|---|
| Constant speed | Continuous, mechanical (spinners, progress bars) |
| Slow start, fast end | Exiting, dismissing |
| Fast start, slow end | Entering, appearing, most interactions |
| Slow start and end | Smooth, natural transitions |
| Elastic, bouncy | Playful, attention-grabbing |
/* UI Feedback - ease-out (most common) */
button {
transition: background-color 200ms ease-out;
}
/* Entering - ease-out */
.modal {
animation: slideIn 400ms ease-out;
}
/* Exiting - ease-in */
.modal.closing {
animation: slideOut 300ms ease-in;
}
/* Continuous - linear */
.spinner {
animation: spin 1s linear infinite;
}
/* Playful - cubic-bezier */
.bounce {
animation: bounce 600ms cubic-bezier(0.34, 1.56, 0.64, 1);
}/* Small movement - short duration */
button:hover {
transform: scale(1.05);
transition: transform 150ms ease-out;
}
/* Medium movement - medium duration */
.modal {
animation: slideIn 400ms ease-out;
}
@keyframes slideIn {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
/* Large movement - longer duration */
.page-transition {
animation: fadeIn 600ms ease-out;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}/* Default state */
button {
background-color: var(--color-primary);
color: white;
transition: background-color 200ms ease-out;
}
/* Hover state */
button:hover:not(:disabled) {
background-color: var(--color-primary-dark);
}
/* Active state */
button:active:not(:disabled) {
background-color: var(--color-primary-darker);
transform: scale(0.98);
}
/* Focus state */
button:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
}
/* Disabled state */
button:disabled {
background-color: var(--color-disabled);
cursor: not-allowed;
opacity: 0.6;
}
/* Loading state */
button.loading {
pointer-events: none;
opacity: 0.8;
}
button.loading::after {
content: '';
display: inline-block;
width: 16px;
height: 16px;
margin-left: 8px;
border: 2px solid rgba(255, 255, 255, 0.3);
border-top-color: white;
border-radius: 50%;
animation: spin 1s linear infinite;
}/* Input default state */
input {
border: 1px solid var(--color-border);
transition: border-color 200ms ease-out, box-shadow 200ms ease-out;
}
/* Input focus state */
input:focus {
border-color: var(--color-primary);
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
}
/* Input valid state */
input.valid {
border-color: var(--color-success);
}
input.valid:focus {
box-shadow: 0 0 0 3px rgba(16, 185, 129, 0.1);
}
/* Input error state */
input.error {
border-color: var(--color-error);
}
input.error:focus {
box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1);
}
/* Error message animation */
.error-message {
animation: slideDown 300ms ease-out;
color: var(--color-error);
font-size: 14px;
margin-top: 4px;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}/* Skeleton loading */
.skeleton {
background: linear-gradient(
90deg,
var(--color-skeleton) 0%,
var(--color-skeleton-light) 50%,
var(--color-skeleton) 100%
);
background-size: 200% 100%;
animation: shimmer 2s infinite;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
/* Spinner */
.spinner {
width: 40px;
height: 40px;
border: 4px solid var(--color-border);
border-top-color: var(--color-primary);
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* Progress bar */
.progress-bar {
height: 4px;
background-color: var(--color-border);
overflow: hidden;
}
.progress-bar-fill {
height: 100%;
background-color: var(--color-primary);
transition: width 300ms ease-out;
}/* Notification container */
.notification {
position: fixed;
top: 20px;
right: 20px;
padding: 16px;
background-color: white;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
animation: slideIn 300ms ease-out;
z-index: 1000;
}
/* Notification variants */
.notification.success {
border-left: 4px solid var(--color-success);
}
.notification.error {
border-left: 4px solid var(--color-error);
}
.notification.warning {
border-left: 4px solid var(--color-warning);
}
/* Notification exit animation */
.notification.exiting {
animation: slideOut 300ms ease-in forwards;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(400px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideOut {
from {
opacity: 1;
transform: translateX(0);
}
to {
opacity: 0;
transform: translateX(400px);
}
}/* Page fade transition */
.page {
animation: fadeIn 400ms ease-out;
}
.page.exiting {
animation: fadeOut 300ms ease-in forwards;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes fadeOut {
from { opacity: 1; }
to { opacity: 0; }
}
/* Page slide transition */
.page {
animation: slideIn 400ms ease-out;
}
.page.exiting {
animation: slideOut 300ms ease-in forwards;
}
@keyframes slideIn {
from {
opacity: 0;
transform: translateX(30px);
}
to {
opacity: 1;
transform: translateX(0);
}
}
@keyframes slideOut {
from {
opacity: 1;
transform: translateX(0);
}
to {
opacity: 0;
transform: translateX(-30px);
}
}transformopacitylefttopwidthheightbackground-colorbox-shadow/* Good - GPU-accelerated */
button:hover {
transform: scale(1.05);
transition: transform 200ms ease-out;
}
/* Avoid - CPU-intensive */
button:hover {
width: 110px;
height: 110px;
transition: width 200ms ease-out, height 200ms ease-out;
}prefers-reduced-motion/* Default animations */
button {
transition: background-color 200ms ease-out;
}
/* Reduced motion */
@media (prefers-reduced-motion: reduce) {
button {
transition: none;
}
}/* Bad - only animation */
button:hover {
transform: scale(1.1);
}
/* Good - animation + color change */
button:hover {
background-color: var(--color-primary-dark);
transform: scale(1.05);
}/* Hover state for mouse users */
button:hover {
background-color: var(--color-primary-dark);
}
/* Focus state for keyboard users */
button:focus-visible {
outline: 2px solid var(--color-focus);
outline-offset: 2px;
background-color: var(--color-primary-dark);
}/* Bad - rapid flashing */
.alert {
animation: flash 100ms infinite;
}
/* Good - subtle, slow animation */
.alert {
animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.7; }
}"I'm using the interaction-design skill. Can you audit my interactions?
- Identify microinteractions that are missing
- Check animation timing and easing
- Identify performance issues (CPU-intensive animations)
- Check accessibility (reduced motion, keyboard navigation)
- Suggest improvements""Can you help me design microinteractions for:
- Button states (hover, active, disabled, loading)
- Form validation feedback
- Loading states
- Success/error notifications
- Page transitions""Can you implement animations for:
- Button hover and active states
- Modal open/close
- Page transitions
- Loading spinner
- Notification entrance/exit
Include timing, easing, and accessibility considerations""Can you optimize my animations for performance?
- Identify CPU-intensive animations
- Suggest GPU-accelerated alternatives
- Check for unnecessary animations
- Ensure smooth 60fps performance""Can you evaluate my interactions?
- Are my animations intentional and purposeful?
- Is my timing appropriate?
- Are my easing functions right?
- Are my interactions accessible?
- What's one thing I could improve immediately?"