Загрузка...

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 — длина: меньше значение — ближе и драматичнее; больше — площе. Ставьте на сцену, не на каждую грань, чтобы соседи делили одну точку схода.

Perspective on the parent

css
.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().

rotateX rotateY rotateZ

css
.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.

translateZ in a 3D scene

css
.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 на вращающуюся обёртку.

preserve-3d on the scene

css
.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 flip with backface-visibility

css
.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-сдвиг). Клавиатурный фокус по-прежнему нужен видимый контур; переворот — не стиль фокуса.

Modest 3D hover not a 2D lift

css
.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 на поле. Если людям с уменьшенным движением нужна статичная карточка — поверьте им.

Попробуйте сами

  1. Оберните карточку в .stage { perspective: 800px; } и задайте ребёнку rotateY(20deg) — затем перенесите perspective в transform ребёнка и сравните соседние плитки.
  2. Соберите двустороннюю карточку: preserve-3d на каркасе, backface-visibility: hidden на обеих гранях, оборот rotateY(180deg).
  3. Добавьте translateZ(32px) на переднюю плоскость; убедитесь, что соседи по вёрстке не сдвигаются.
  4. Переверните классом + transition: transform — затем сплющите через prefers-reduced-motion.
  5. Не решайте это через cursor, resize или только 2D-hover translateY.

Частые ошибки

  • 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 в карте нет

🧠 Проверьте Свои Знания

Готов к Началу

Проверьте Свои Знания

Бросьте себе вызов с помощью этой интерактивной викторины и узнайте, насколько хорошо вы понимаете тему

❓
7
Вопросы
🎯
70%
Для Прохождения
♾️
∞
Время
🔄
∞
Попытки

📝 Инструкции

  • Внимательно прочитайте каждый вопрос
  • Выберите лучший ответ на каждый вопрос
  • Вы можете пересдавать тест столько раз, сколько захотите
  • Ваш прогресс будет показан вверху