position
حرکتهای دقیق UI از اسلاید و مسیر تا شناوری و مدار را طراحی کنید.
این Skill برای طراحی انیمیشنهای حرکتی و جابهجایی در UI و موشنگرافیک استفاده میشود؛ از ورود و خروج اسلایدی تا حرکت روی مسیرهای قوسی، drift، orbit و overshoot.
با تکیه بر توکنهای استاندارد W3C و الگوهای Material Design 3، فاصله، جهت، مسیر و شدت حرکت را منسجم انتخاب میکند و نمونههای آماده برای CSS، Framer Motion و GSAP ارائه میدهد.
چه چیزی میگیرید
- انتخاب offset و direction مناسب برای ورود، خروج و ترنزیشن عناصر
- الگوهای آماده برای حرکت خطی، قوسی، شناور و مداری
- پارامترهای overshoot برای فرودهای نرم و spring-like
- راهنمای استفاده از توکنهای position در CSS، Framer Motion و GSAP
- پیشنهادهای سازگار با prefers-reduced-motion برای دسترسپذیری
برای چه کاری خوب است
- طراحی ترنزیشنهای ورود و خروج برای کارتها، مودالها، پنلها و صفحات
- ساخت عناصر تزئینی شناور یا orbiting در رابطهای کاربری و موشنگرافیک
- پیادهسازی حرکت طبیعی روی مسیر برای تعاملات، onboarding و انیمیشنهای محصول
برای چه کاری نیست
- طراحی کامل سیستم easing یا زمانبندی بدون نیاز به حرکت مکانی
- ساخت انیمیشنهای پیچیده و چندمرحلهای ویدیو که به timeline یا تدوین کامل نیاز دارند
- پروژههایی که به حرکت یا انیمیشن وابسته نیستند
دربارهٔ این اسکیل
Position
Movement and translation animations for UI elements and motion graphics.
Standards Reference
| Standard | Documentation |
|---|---|
| W3C DTCG | designtokens.org |
| Material Design 3 | m3.material.io/styles/motion |
| CSS Transforms | developer.mozilla.org/CSS/transform |
Quick Reference
Load from: tokens/position.tokens.json
Offset Distances
| Token | Value | Use |
|---|---|---|
micro | 4px | Hover states, icon nudges |
small | 8px | Button press feedback |
medium | 16px | Card entrances, modal slides |
large | 32px | Drawer slides, panel transitions |
xlarge | 64px | Hero entrances, page transitions |
viewport-full | 100vw | Page swipes, carousel slides |
Directions
| Token | Vector | Use |
|---|---|---|
up | (0, -1) | Entrance from below (slide up) |
down | (0, 1) | Dropdowns, gravity effects |
left | (-1, 0) | Forward navigation (LTR) |
right | (1, 0) | Back navigation (LTR) |
Selection Guide
What type of movement?
│
├── ENTRANCE/EXIT → Use offset + direction
│ ├── Subtle → micro (4px)
│ ├── Standard → medium (16px)
│ └── Dramatic → xlarge (64px)
│
├── CONTINUOUS → Use drift or orbit
│ ├── Ambient background → drift (slow period)
│ └── Loading/decorative → orbit (medium speed)
│
├── SPRING SETTLE → Use overshoot
│ ├── Subtle → 1.02 (2%)
│ ├── Playful → 1.1 (10%)
│ └── Cartoon → 1.5 (50%)
│
└── PATH-BASED → Use path tokens
├── Mechanical → linear
├── Natural → arc-medium
└── Theatrical → arc-pronounced
Patterns
Slide Up Entrance
Element slides up into view with fade.
CSS:
.slide-up-enter {
opacity: 0;
transform: translateY(16px); /* {motion.position.offset.medium} */
}
.slide-up-enter-active {
opacity: 1;
transform: translateY(0);
transition: all 250ms cubic-bezier(0.05, 0.7, 0.1, 1); /* M3 emphasized-decelerate */
}
Framer Motion:
const slideUpVariants = {
hidden: {
opacity: 0,
y: 16 // {motion.position.offset.medium}
},
visible: {
opacity: 1,
y: 0,
transition: {
duration: 0.25, // {motion.duration.medium-1}
ease: [0.05, 0.7, 0.1, 1] // emphasized-decelerate
}
}
};
GSAP:
gsap.from(element, {
y: 16, // {motion.position.offset.medium}
opacity: 0,
duration: 0.25,
ease: "power2.out"
});
Arc Motion
Natural curved path between two points.
GSAP MotionPath:
gsap.to(element, {
motionPath: {
path: [
{ x: 0, y: 0 },
{ x: 100, y: -50 }, // control point at 25% height
{ x: 200, y: 0 }
],
curviness: 1.25 // {motion.position.path.arc-medium}
},
duration: 0.4,
ease: "power2.inOut"
});
Framer Motion:
<motion.div
animate={{
x: [0, 100, 200],
y: [0, -50, 0] // arc path
}}
transition={{
duration: 0.4,
ease: [0.4, 0, 0.2, 1],
times: [0, 0.5, 1]
}}
/>
Floating Drift
Ambient floating animation for background elements.
CSS Keyframes:
@keyframes drift {
0%, 100% {
transform: translate(0, 0);
}
25% {
transform: translate(4px, -8px); /* subtle amplitude */
}
50% {
transform: translate(-4px, 4px);
}
75% {
transform: translate(8px, -4px);
}
}
.floating-element {
animation: drift 6s ease-in-out infinite; /* {motion.position.drift.period-slow} */
}
Framer Motion:
<motion.div
animate={{
x: [0, 4, -4, 8, 0],
y: [0, -8, 4, -4, 0]
}}
transition={{
duration: 6, // {motion.position.drift.period-slow}
repeat: Infinity,
ease: "easeInOut"
}}
/>
Overshoot Settle
Spring-like overshoot and settle animation.
Framer Motion Spring:
<motion.div
animate={{ x: 0 }}
initial={{ x: -100 }}
transition={{
type: "spring",
stiffness: 200,
damping: 15,
// Results in ~10% overshoot {motion.position.overshoot.medium}
}}
/>
GSAP:
gsap.to(element, {
x: 0,
duration: 0.5,
ease: "back.out(1.7)" // ~10% overshoot
});
Orbit Animation
Circular motion around a center point.
CSS:
@keyframes orbit {
from {
transform: rotate(0deg) translateX(48px) rotate(0deg);
}
to {
transform: rotate(360deg) translateX(48px) rotate(-360deg);
}
}
.orbiting-element {
animation: orbit 4s linear infinite; /* {motion.position.orbit.speed-medium} */
}
GSAP:
gsap.to(element, {
motionPath: {
path: "M0,0 a48,48 0 1,1 0,0.1", // {motion.position.orbit.radius-medium}
autoRotate: false
},
duration: 4, // {motion.position.orbit.speed-medium}
repeat: -1,
ease: "none"
});
Reduced Motion
For prefers-reduced-motion: reduce:
| Full Motion | Reduced Alternative |
|---|---|
| Slide 16px+ | Fade only (no movement) |
| Arc motion | Linear fade or instant |
| Drift/float | Static position |
| Orbit | Static position |
| Overshoot | Simple ease-out |
Implementation:
@media (prefers-reduced-motion: reduce) {
.slide-up-enter {
transform: none;
/* Keep opacity transition only */
}
.floating-element {
animation: none;
}
}
Cross-References
- See
easing/for timing curves applied to position animations - See
duration/for animation timing values - See
entrance-patterns/for complete entrance animations using position - See
exit-patterns/for complete exit animations using position - See
sequencing/for staggered position animations - See
motion-principles/for arc motion (Disney Principle #7)
References
references/path-types.md— Detailed path motion implementations