جابه‌جایی بدون تأثیر بر Layout: translate، translateX، translateY و translateZ

وارد فصل نوزدهم شدیم؛ فصلی که به Transforms اختصاص داره. در فصل ۱۵ (درس ۱۵-۵)، یک معرفی کلی از خانواده توابع Transform داشتیم؛ حالا وقتشه هرکدوم از این خانواده‌ها رو، به‌طور مستقل و کامل، بررسی کنیم. شروع می‌کنیم با خانواده translate، که مسئول جابه‌جایی عناصره.

یادآوری سریع: چرا transform روی Layout اثر نمی‌گذارد؟

همون‌طور که در فصل ۱۵ و ۱۸ دیدیم، Property به اسم transform، برخلاف margin یا top/left (که در فصل ۱۰ دیدیم)، هیچ فضایی از جریان چیدمان رو تغییر نمی‌ده؛ فقط لایه بصری عنصر رو، بعد از این‌که Layout واقعی محاسبه شد، جابه‌جا می‌کنه. این ویژگی، دقیقاً همون چیزیه که transform رو برای انیمیشن‌های روان، در فصل ۱۸، انتخاب برتر می‌کرد.

translateX(): جابه‌جایی افقی

.box {
  transform: translateX(50px);
}

translateX()، عنصر رو، فقط در محور افقی، جابه‌جا می‌کنه؛ مقدار مثبت، به سمت راست (در جهت پیش‌فرض LTR)، و مقدار منفی، به سمت چپ.

translateY(): جابه‌جایی عمودی

.box {
  transform: translateY(-20px);
}

translateY()، همون کار رو، برای محور عمودی انجام می‌ده؛ مقدار مثبت، به سمت پایین، و مقدار منفی (مثل این مثال)، به سمت بالا.

translate(): هر دو محور، هم‌زمان

.box {
  transform: translate(50px, -20px);
}

translate()، دو مقدار می‌گیره: اول X، بعد Y؛ این تابع، دقیقاً معادل نوشتن translateX(50px) translateY(-20px) پشت‌سرهمه، ولی کوتاه‌تر و رایج‌تر.

پشتیبانی از واحدهای درصدی: نسبت به خود عنصر، نه والد

.box {
  transform: translateX(-50%);
}

یک نکته بسیار مهم که translate رو از خیلی از Propertyهای دیگه متمایز می‌کنه: وقتی از درصد استفاده می‌شه، این درصد، نسبت به ابعاد خود همون عنصر محاسبه می‌شه، نه نسبت به والدش (برخلاف چیزی که در فصل ۶ برای width یا padding دیدیم، که درصد، همیشه نسبت به والد بود). یعنی translateX(-50%)، یعنی «به اندازه نصف عرض خودِ این عنصر، به چپ برو».

یادآوری کاربرد کلیدی: وسط‌چین کردن دقیق

.centered {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}

همون‌طور که در فصل ۱۰ (درس ۱۰-۴) و فصل ۱۵ (درس ۱۵-۵) دیدیم، این الگو، رایج‌ترین تکنیک وسط‌چین کردن دقیق یک عنصره: top: 50% و left: 50% (که در فصل ۱۰ دیدیم)، گوشه بالا-چپ عنصر رو، دقیقاً وسط والدش می‌بره؛ و translate(-50%, -50%)، عنصر رو، به‌اندازه نصف ابعاد خودش، به عقب می‌کشه تا مرکز واقعیش، دقیقاً روی همون نقطه وسط قرار بگیره؛ این ترکیب، مستقل از این‌که عنصر، چه ابعاد دقیقی داره (که ممکنه از قبل، مشخص نباشه)، همیشه کار می‌کنه.

translateZ(): جابه‌جایی در محور عمق (سه‌بعدی)

.box {
  transform: translateZ(50px);
}

translateZ()، برخلاف دو مورد قبلی، عنصر رو، در یک محور سوم و جدید، یعنی محور عمق (Z)، جابه‌جا می‌کنه؛ مقدار مثبت، عنصر رو، به سمت بیننده (به‌نظر بزرگ‌تر) نزدیک می‌کنه، و مقدار منفی، اون رو دورتر (به‌نظر کوچک‌تر) می‌بره.

پیش‌نیاز مهم برای translateZ(): perspective

.scene {
  perspective: 500px;
}

.box {
  transform: translateZ(100px);
}

یک نکته حیاتی: بدون تعریف Property به اسم perspective (که در درس‌های بعدی همین فصل، با جزئیات کامل، بررسیش می‌کنیم)، روی والد عنصر، translateZ()، هیچ اثر بصری قابل‌مشاهده‌ای نداره؛ چون مرورگر، بدون این Property، هیچ «دیدگاه سه‌بعدی» برای نمایش عمق نداره، و عنصر، همچنان، از دید بیننده، مسطح به‌نظر می‌رسه.

translate3d(): جابه‌جایی هر سه محور، هم‌زمان

.box {
  transform: translate3d(50px, -20px, 30px);
}

translate3d()، سه مقدار می‌گیره (X، Y، Z، به همین ترتیب) و معادل نوشتن هر سه تابع مجزا، پشت‌سرهمه.

یک نکته درباره Performance: چرا گاهی translate3d() به translate() ترجیح داده می‌شود؟

.optimized {
  transform: translate3d(20px, 0, 0);
}

یک تکنیک شناخته‌شده (هرچند امروزه، در بسیاری از مرورگرهای مدرن، اهمیتش کمتر شده): استفاده از translate3d()، حتی وقتی فقط جابه‌جایی دوبعدی مدنظره (با گذاشتن مقدار Z برابر صفر)، گاهی باعث می‌شه مرورگر، پردازش اون عنصر رو، به کارت گرافیک (GPU) بسپاره، نه فقط پردازنده اصلی (CPU)؛ این کار، می‌تونه در انیمیشن‌های پیچیده و پرتکرار، Performance رو بهبود بده. جزئیات فنی این موضوع رو، در فصل CSS Performance، دقیق‌تر بررسی می‌کنیم.

جدول جمع‌بندی خانواده translate

تابع محور نیاز به perspective
translateX() افقی خیر
translateY() عمودی خیر
translate() افقی + عمودی خیر
translateZ() عمق (سه‌بعدی) بله
translate3d() هر سه محور بله (برای اثر واقعی روی Z)

یک مثال کامل: کارت با جابه‌جایی هنگام Hover

.card {
  transform: translateY(0);
  transition: transform 0.2s ease-out;
}

.card:hover {
  transform: translateY(-8px);
}

این الگو، که ترکیبی از این درس و فصل ۱۸ (Transitions) است، یکی از رایج‌ترین جلوه‌های تعاملی در طراحی مدرنه: کارت، هنگام Hover، کمی به سمت بالا «شناور» می‌شه؛ این جابه‌جایی، چون با transform انجام می‌شه (نه margin-top)، هیچ فضایی از Layout رو تغییر نمی‌ده و کاملاً روان اجرا می‌شه.

نکات مهم

  • translate، برخلاف تغییر margin یا top/left، هیچ تأثیری روی Layout واقعی صفحه ندارد و فقط لایه بصری را جابه‌جا می‌کند.
  • مقادیر درصدی در translate، نسبت به ابعاد خود عنصر محاسبه می‌شوند، نه والدش؛ این ویژگی، پایه تکنیک وسط‌چین کردن دقیق است.
  • translateZ() و translate3d()، بدون تعریف Property به اسم perspective روی والد، هیچ اثر بصری قابل‌مشاهده‌ای ندارند.

اشتباهات رایج

  • تصور اینکه درصد در translateX/translateY، نسبت به والد محاسبه می‌شود؛ در حالی که نسبت به ابعاد خود عنصر است.
  • استفاده از translateZ() بدون تعریف perspective روی والد، که باعث می‌شود هیچ تغییر بصری قابل‌مشاهده‌ای رخ ندهد.
  • استفاده از margin یا top/left برای جلوه‌های تعاملی مکرر (مثل Hover)، به‌جای translate که هزینه محاسباتی کمتری دارد.

جمع‌بندی

خانواده translate (translateX، translateY، translate، translateZ، translate3d)، عنصر را در محورهای افقی، عمودی و عمق، بدون تأثیر بر Layout واقعی صفحه، جابه‌جا می‌کند. مقادیر درصدی در این توابع، نسبت به ابعاد خود عنصر محاسبه می‌شوند که این ویژگی، پایه تکنیک رایج وسط‌چین کردن دقیق است؛ در حالی که توابع مربوط به محور Z، برای اثرگذاری واقعی، نیازمند تعریف Property به اسم perspective روی والد هستند.