کوریوگرافی چیدمان به جای پرش عناصر
خلاصهٔ کاملتر
نویسنده با یه مشاهدهٔ ساده شروع میکنه: رابطهای کاربری مدام تلپورت میکنن. یه آیتم رو از لیست حذف میکنی و بقیه یهو میپرن بالا، یا یه پنل باز میشه و بلوکهای کناری بلافاصله جابهجا میشن. از نظر DOM هیچی غلط نیست؛ مشکل ادراکیه. کاربر انتظار داره آیتم سوم و چهارم بیان تو فضای خالی، ولی اونا فقط یهو اونجا ظاهر میشن. کوریوگرافی چیدمان یعنی به همین جابهجایی یه مسیر قابل دیدن بدیم.
مدل استاندارد این کار FLIP هست: اول جعبهٔ فعلی عنصر با getBoundingClientRect ثبت میشه (First)، بعد تغییر state اعمال و جعبهٔ جدید ثبت میشه (Last)، بعد عنصر با transform به جای قبلیش برگردونده میشه (Invert) و آخرش همون transform تا صفر انیمیت میشه (Play). به گفتهٔ نویسنده نکتهٔ حیاتی اینه که هیچوقت top، left، height یا margin رو انیمیت نکنی؛ اینا پراپرتیهای layout هستن و مرورگر رو مجبور میکنن وسط انیمیشن دوباره هندسه رو حساب کنه.
خود نویسنده میگه معمولاً FLIP رو دستی نمینویسه و از پراپ layout در Motion استفاده میکنه. layout حرکت آیتمهای همسایه رو مدیریت میکنه، AnimatePresence آیتم حذفشده رو اونقدر زنده نگه میداره که انیمیشن خروجش تموم بشه، و mode="popLayout" اجازه میده آیتم در حال خروج از جریان صفحه بیرون بره تا بقیه بلافاصله جاشون رو عوض کنن.
<motion.div
key={item.id}
layout
exit={{ opacity: 0, scale: 0.5, filter: "blur(6px)" }}
transition={{ type: "spring", stiffness: 400, damping: 30 }}
>
{item.label}
</motion.div>یه نکتهٔ ظریف اینه که خروج آیتم و جابهجایی همسایهها دو انیمیشن جدان و باید جدا تنظیم بشن. آیتم در حال خروج میتونه سریع و قاطع باشه چون داره میره، ولی همسایهها به زمان کافی نیاز دارن تا مسیرشون خونده بشه؛ نویسنده برای تغییرات کوچیک حدود ۲۰۰ تا ۳۵۰ میلیثانیه یا یه spring با میرایی کافی رو پیشنهاد میده. ترتیب هم مهمه: اول چیزی که کاربر بهش دست زده واکنش نشون بده، بعد چیدمان اطراف خودش رو باهاش تطبیق بده.
نویسنده هشدار میده که FLIP معمولاً برای تغییر عرض و ارتفاع از scale استفاده میکنه و همین میتونه بچههای کامپوننت رو خراب کنه: متن کش میاد، بوردر کلفت میشه و شعاع گوشهها بد به نظر میرسه. راهحلها کوچیکن؛ scale رو کم نگه دار، متن رو تو یه wrapper داخلی بذار و border-radius رو صریح انیمیت کن. در آخر، چون این حرکتها واقعاً اجسام رو تو فضا جابهجا میکنن، حتماً باید یه مسیر reduced-motion داشته باشن که transform رو بذاره کنار ولی محتوا و ترتیب سرجاش بمونه.
نکات کلیدی:
- مشکل پرش چیدمان ادراکیه نه فنی؛ DOM درسته ولی پیوستگی بصری از بین میره.
- FLIP یعنی ثبت موقعیت قبل و بعد، برگردوندن عنصر با transform و انیمیت کردنش تا صفر.
- فقط transform رو انیمیت کن؛ top، left و height مرورگر رو مجبور به محاسبهٔ دوبارهٔ چیدمان میکنن.
- پراپ layout در Motion بههمراه AnimatePresence و mode="popLayout" همین رفتار رو آماده میده.
- انیمیشن خروج و جابهجایی همسایهها رو جدا تنظیم کن؛ برای تغییرات کوچیک حدود ۲۰۰ تا ۳۵۰ میلیثانیه.
- View Transitions برای تغییر مسیر و اسنپشات صفحه خوبه، ولی لیستهای تعاملی به عنصرهای زنده نیاز دارن.
- مسیر reduced-motion رو فراموش نکن و هر ریفلویی رو هم بیدلیل انیمیت نکن.




