تبدیل سهبعدی در CSS
جلسهٔ قبل اشارهگر و caret و پوست ویجت بومی را تنظیم کرد. این آخرین جلسهٔ اختیاری چیز دیگری است: تبدیل سهبعدی. به کارت نقطهٔ گریز میدهید و در عمق کجش میکنید. نه درس هاور translate و scale دوبعدی را تکرار میکنید، نه cursor و دستگیرهٔ resize میچینید.
جواب مستقیم
تبدیل سهبعدی در CSS همان ویژگی transform دوبعدی است، بهاضافهٔ عمق. perspective را روی والد بگذارید تا بچهها یک نقطهٔ گریز مشترک داشته باشند (perspective-origin آن نقطه را جابهجا میکند). rotateX و rotateY حول محور افقی و عمودی کج میکنند؛ rotateZ همان چرخش تخت آشناست. translateZ به بیننده نزدیک یا از او دور میشود. transform-style: preserve-3d بچهها را در یک صحنه نگه میدارد تا صاف نشوند. backface-visibility: hidden وقتی چهره پشت میکند پنهانش میکند — برای کارت دو رو مفید است. جای چیدمان مثل ۲بعدی سر جایش میماند. زاویه را کوچک بگیرید. prefers-reduced-motion را جدی بگیرید.
چرا این حرکت دوبعدی نیست و UI هم نیست
درس تبدیل دوبعدی حرکت روی صفحه را گفت: translate، rotate، scale، skew و لولای transform-origin. همانها هنوز کار میکنند. سهبعدی یک perspective شبیه دوربین و محور اضافه میآورد. رابط کاربری پوست تعامل بود (cursor، resize، caret-color، appearance). کارت چرخیده دست دروغ لازم ندارد و دستگیرهٔ textarea نقطهٔ گریز نیست. اگر فقط دو پیکسل بالا رفتن میخواهید، همان ۲بعدی کافی است.
perspective — دوربین را روی والد بگذارید
perspective یک طول است: عدد کوچکتر نزدیکتر و تندتر حس میشود؛ عدد بزرگتر صافتر. روی صحنه بگذارید، نه روی تکتک چهرهها، تا همسطحها یک نقطهٔ گریز داشته باشند.
.stage {
perspective: 800px;
perspective-origin: 50% 40%;
}
.card-3d {
transform: rotateY(18deg);
transform-origin: center;
}
میشود روی یک عنصر هم نوشت transform: perspective(800px) rotateY(18deg). آن دوربین فقط مال همان جعبه است. برای مکعب یا ردیف کاشی، perspective والد آرامتر است. perspective-origin پسرعموی نقطهٔ گریز برای transform-origin است — جای لولای چهره را عوض نمیکند.
محورها — rotateX، rotateY، rotateZ
کتاب را تصور کنید. rotateY جلد را چپراست باز میکند. rotateX آن را به شما نزدیک یا دور خم میکند. rotateZ روی صفحه میچرخاند — همان rotate() دوبعدی.
.tile-y {
transform: rotateY(-22deg);
}
.tile-x {
transform: rotateX(12deg);
}
.tile-z {
transform: rotateZ(8deg);
}
وقتی هر دو لازم است با توابع دوبعدی زنجیر کنید: rotateY(16deg) translateZ(24px). ترتیب مهم است — تابع بعدی در فضای محلی قبلی اجرا میشود. مثل درس ۲بعدی، یک فهرست transform کافی است. rotateX(80deg) روی کل مقاله کارناوال است، نه رابط.
translateZ — فاصله، نه هل چیدمان
با perspective، translateZ مثبت معمولاً به سمت بیننده میآید. همسایههای سند جا باز نمیکنند؛ فقط نقاشی جابهجا میشود، مثل translate دوبعدی.
.stage {
perspective: 900px;
}
.pop-face {
transform: translateZ(40px) rotateY(-8deg);
}
.back-face {
transform: translateZ(-28px);
}
translateZ چهرههای یک صحنه را از هم جدا میکند؛ جای margin یا z-index معمولی نیست. z-index هنوز جعبهٔ همپوشان را در چیدمان دوبعدی مرتب میکند؛ فاصلهٔ سهبعدی پیچ دیگری است. اگر کار «تراشه را دو پیکسل بالا ببر» است، همان translateY درس ۲بعدی بس است.
preserve-3d — صحنه را نگه دارید، صاف نکنید
پیشفرض این است که والد بچههای تبدیلشده را صاف میکند (transform-style: flat). آنوقت رابطهٔ سهبعدی از بین میرود. برای مکعب، جلد رویهم، یا کارت دو رو، روی پوششِ چرخان preserve-3d بگذارید.
.scene {
perspective: 700px;
}
.rig {
transform-style: preserve-3d;
transition: transform 0.45s ease;
}
.rig.is-flipped {
transform: rotateY(180deg);
}
.face {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
هر نیایی که باید عمق را نگه دارد preserve-3d میخواهد — یک والد flat فراموششده مکعب را پوستر میکند. اغلب perspective روی صحنهٔ بیرونی است و preserve-3d روی دکل داخلی: دوربین بیرون، مفصلها داخل.
backface-visibility — پشت را پنهان کنید
وقتی چهره از ۹۰ درجه میگذرد، در غیر این صورت آینهاش دیده میشود. backface-visibility: hidden آن پشت را برمیدارد. دو چهره جفت کنید: رو rotateY(0)، پشت rotateY(180deg)، هر دو position: absolute روی همان دکل.
.card-rig {
position: relative;
transform-style: preserve-3d;
}
.card-front,
.card-back {
position: absolute;
inset: 0;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(180deg);
}
بدون پشتِ پنهان، شبح روی کارت از جلو دیده میشود. این نه user-select: none است نه appearance: none. دارید چهرهٔ نقاشیشده را در سهبعد پنهان میکنید، نه پوست چکباکس را میکَنید.
سهبعدی در برابر تبدیل دوبعدی و پوستهٔ UI
📊 3D vs 2D transform vs UI chrome
| Tool | Job | Poor fit |
|---|---|---|
perspective + rotateX / rotateY / translateZ |
صحنهٔ عمق: کج شدن، فاصله، نقطهٔ گریز مشترک | هاور دو پیکسلی روزمره؛ شکل اشارهگر |
2D translate / rotate / scale / skew |
حرکت روی صفحه؛ لولای origin | ساخت مکعب بدون preserve-3d |
transform-style / backface-visibility |
چهرههای تودرتوی سهبعدی؛ پنهان کردن پشت | رنگ caret؛ resize فیلد |
UI (cursor، resize، appearance…) |
پوستهٔ تعامل روی کنترل | نقطهٔ گریز؛ ورق زدن کارت |
Optional Advanced قبلاً کنترل را استایل داد. Effects & Motion نگاشت دوبعدی را گفت. این جلسه لایهٔ عمق روی transform است. cursor: pointer روی تیتری که rotateY دارد آن را سهبعدی نمیکند. perspective روی فرم ورود جای resize فیلد یادداشت را نمیگیرد.
عادتهای آرام
برای کارت رابط، perspective را در حد چند صد پیکسل نگه دارید (بازهٔ معقول حدود 600px تا 1200px). perspective: 40px روی body نگذارید. هاور یا کلاس را با transition کوتاه روی transform جفت کنید — همان عادت ۲بعدی. جلوه را با prefers-reduced-motion: reduce ببندید (none یا یک تلنگر کوچک دوبعدی). فوکوس صفحهکلید هنوز حلقهٔ دیدنی درسهای قبل را میخواهد؛ ورق زدن کارت استایل فوکوس نیست.
.preview {
perspective: 1000px;
}
.preview .plate {
transition: transform 0.3s ease;
}
.preview:hover .plate {
transform: rotateY(-10deg) rotateX(4deg);
}
@media (prefers-reduced-motion: reduce) {
.preview .plate,
.preview:hover .plate {
transition: none;
transform: none;
}
}
این هاور کج شدن است، نه بالا رفتن تراشه با translateY(-0.15rem) دوبعدی، و نه resize: vertical روی فیلد. اگر کاربر کاهش حرکت کارت ثابت میخواهد، حرفش را گوش کنید.
خودتان امتحان کنید
- کارت را در
.stage { perspective: 800px; }بپیچید و روی بچهrotateY(20deg)بگذارید — بعدperspectiveرا بهtransformخود بچه ببرید و کاشیهای همسطح را مقایسه کنید. - کارت دو رو بسازید:
preserve-3dروی دکل،backface-visibility: hiddenروی هر دو چهره، پشت باrotateY(180deg). - روی صفحهٔ جلو
translateZ(32px)بگذارید؛ ببینید همسایهٔ چیدمان تکان نمیخورد. - با کلاس و
transition: transformورق بزنید — بعد باprefers-reduced-motionصافش کنید. - این کار را با
cursor،resizeیا فقطtranslateYدوبعدی حل نکنید.
اشتباهات رایج
perspective: 50pxرویbodyتا کل صفحه تاب بردارد- فراموش
preserve-3dروی پوشش، بعد تعجب که مکعب صاف شده - بالا بردن تراشهٔ دوبعدی (
translateY) را درس سهبعدی دانستن - پوستهٔ UI (
cursor،resize،appearance) را جای عمق گذاشتن backface-visibilityروی صحنه بهجای چهرهها- نادیده گرفتن
prefers-reduced-motionرویrotateYبزرگ - انتظار اینکه سهبعدی مثل
marginجریان سند را عوض کند
خلاصه
- تبدیل سهبعدی به
transformعمق میدهد: perspective،rotateX/rotateY،translateZ - perspective را روی صحنهٔ والد بگذارید؛ با preserve-3d چهرههای تودرتو در همان فضا بمانند
- backface-visibility: hidden چهرهای را که پشت کرده پنهان میکند
- نه درس هاور دوبعدی است نه پوستهٔ رابط کاربری
- زاویه را کوچک بگیرید؛ کاهش حرکت را رعایت کنید
- این آخرین جلسهٔ CSS این کورس است — Optional Advanced اینجا تمام میشود؛ اسلاگ CSS دیگری در نقشه نیست
🧠 دانش خود را بیازمایید
دانش خود را بیازمایید
خود را با این آزمون تعاملی به چالش بکشید و ببینید موضوع را چقدر خوب درک کردهاید
📝 دستورالعملها
- هر سوال را با دقت بخوانید
- بهترین پاسخ را برای هر سوال انتخاب کنید
- میتوانید آزمون را هر چند بار که میخواهید تکرار کنید
- پیشرفت شما در بالا نمایش داده میشود