3D-трансформации в CSS
Optional Advanced только что настроил указатель, каретку и нативный хром. Последний необязательный урок — другой набор: 3D-трансформации. Карточке дают точку схода и наклоняют её в глубину. Это не повтор 2D-урока с translate / scale при наведении и не выбор курсора или ручки resize.
Прямой ответ
3D-трансформации CSS — то же свойство transform, что и в 2D, плюс глубина. Ставьте perspective на родителя, чтобы дети делили точку схода (perspective-origin её сдвигает). rotateX и rotateY наклоняют вокруг горизонтальной и вертикальной осей; rotateZ — знакомый плоский поворот. translateZ приближает или отдаляет от зрителя. transform-style: preserve-3d держит детей в одной сцене, а не сплющивает. backface-visibility: hidden прячет грань, когда она отворачивается — удобно для двусторонней карточки. Слот в потоке остаётся, как в 2D. Углы скромные. Уважайте prefers-reduced-motion.
Почему это не 2D-движение и не UI-хром
Урок 2D-трансформаций учил движению в плоскости: translate, rotate, scale, skew и шарнир transform-origin. Это по-прежнему работает. 3D добавляет камерную perspective и лишние оси. CSS интерфейса был хромом взаимодействия (cursor, resize, caret-color, appearance). Повёрнутой карточке не нужна лживая рука, а ручка textarea — не точка схода. Нужен подъём на 2px — оставайтесь в 2D.
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 крутит на странице — тот же 2D rotate().
.tile-y {
transform: rotateY(-22deg);
}
.tile-x {
transform: rotateX(12deg);
}
.tile-z {
transform: rotateZ(8deg);
}
При необходимости цепляйте 2D-функции: rotateY(16deg) translateZ(24px). Порядок важен — следующие идут в локальном пространстве предыдущих. Один список transform, как на 2D-уроке. Огромный rotateX(80deg) на всей статье — ярмарка, не интерфейс.
translateZ — расстояние, не толчок вёрстки
С perspective положительный translateZ часто идёт к зрителю. Соседи в документе не расступаются; двигается только краска, как у 2D translate.
.stage {
perspective: 900px;
}
.pop-face {
transform: translateZ(40px) rotateY(-8deg);
}
.back-face {
transform: translateZ(-28px);
}
translateZ разделяет грани сцены, а не подменяет margin или обычный z-index. z-index по-прежнему упорядочивает перекрывающиеся блоки в 2D-вёрстке; 3D-расстояние — другая ручка. Задача «поднять чип на 2px» решается translateY с 2D-урока.
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 — спрятать оборот
Когда грань проходит 90°, иначе виден её зеркальный вид. 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. Вы прячете нарисованную грань в 3D, а не сдираете кожу с чекбокса.
3D против 2D-трансформа и UI-хрома
📊 3D vs 2D transform vs UI chrome
| Tool | Job | Poor fit |
|---|---|---|
perspective + rotateX / rotateY / translateZ |
Сцена глубины: наклон, расстояние, общая точка схода | Повседневный hover на 2px; форма указателя |
2D translate / rotate / scale / skew |
Движение в плоскости; шарнир origin | Куб без preserve-3d |
transform-style / backface-visibility |
Вложенные 3D-грани; скрыть оборот | Цвет каретки; resize поля |
UI (cursor, resize, appearance…) |
Хром взаимодействия на контролах | Точки схода; переворот карточки |
Optional Advanced уже стилизовал контролы. Effects & Motion уже учил 2D-отображение. Этот урок — слой глубины на transform. cursor: pointer на заголовке из‑за rotateY не делает его трёхмерным. perspective на форме входа не заменяет resize поля заметок.
Спокойные привычки
Для карточек интерфейса держите perspective в сотнях пикселей (600px–1200px — здравый диапазон). Не ставьте perspective: 40px на body. Связывайте :hover или класс с коротким transition на transform — как в 2D. Глушите украшение через prefers-reduced-motion: reduce (none или крошечный 2D-сдвиг). Клавиатурный фокус по-прежнему нужен видимый контур; переворот — не стиль фокуса.
.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;
}
}
Этот hover — наклон, не 2D-подъём чипа 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или только 2D-hovertranslateY.
Частые ошибки
perspective: 50pxнаbody, пока не поведёт всю страницу- Забыть
preserve-3dна обёртке и удивляться плоскому кубу - Считать 2D-подъём чипа (
translateY) уроком 3D - Подменять глубину UI-хромом (
cursor,resize,appearance) backface-visibilityна сцене, а не на гранях- Игнорировать
prefers-reduced-motionна большихrotateY - Ждать, что 3D изменит поток документа как
margin
Кратко
- 3D-трансформации дают
transformглубину: perspective,rotateX/rotateY,translateZ - perspective на родительской сцене; preserve-3d, чтобы вложенные грани остались в том пространстве
- backface-visibility: hidden прячет отвернувшуюся грань
- Это не урок 2D-hover и не хром интерфейса
- Скромные углы; уважение к уменьшенному движению
- Последний урок CSS в этом курсе — Optional Advanced здесь заканчивается; следующего CSS-slug в карте нет
🧠 Проверьте Свои Знания
Проверьте Свои Знания
Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему
📝 Инструкции
- Внимательно прочитайте каждый вопрос
- Выберите лучший ответ на каждый вопрос
- Вы можете пересдавать тест столько раз, сколько захотите
- Ваш прогресс будет показан вверху