Добавьте еще одно измерение к веб-страницам с помощью новых функций 3D-преобразования в CSS. Разберемся с масштабированием, вращением, перспективой, а также проблемами z-index и подводными камнями браузеров.
HTML-элементы могут быть трансформированы в трех направлениях:
- горизонтальная ось X;
- вертикальная ось Y;
- и уходящая вглубь монитора ось Z.
Считается, что поверхность экрана — это начало Z-оси. Объекты с положительными Z-координатами будут выдвигаться ближе к пользователю, а с отрицательными — перемещаться вдаль. При добавлении перспективы слой с большим отрицательным Z-значением может полностью пропасть.
Следует отметить несколько моментов:
- CSS может только преобразовать двумерные элементы HTML в трехмерном пространстве. Сами элементы остаются плоскими и имеют нулевую глубину. Масштабирование в z-плоскости не сделает из квадрата куб. В принципе, вы можете создать полноценный куб, но для этого потребуется шесть элементов: по одному для каждой стороны.
- 3D-преобразования отлично подходят для создания эффектов страницы, но вряд ли позволят создать следующий MineCraft или Call of Duty. Сложные модели лучше реализовать с использованием WebGL.
3D преобразования хорошо поддерживаются во всех современных браузерах (включая IE10+) с некоторыми исключениями:
- Internet Explorer не поддерживает
transform-style: preserve-3d
, что делает невозможным создание 3D сцен. - Все версии Safari должны использовать префикс
-webkit-backface-visibility
для скрытия задних граней. Все остальные браузеры поддерживают свойствоbackface-visibility
.
На примере вы можете увидеть, как работают CSS-трансформации, которые будут разобраны ниже:
See the Pen 3D transform functions by Craig Buckler (@craigbuckler) on CodePen.
transform
К любому элементу можно применить свойство transform
. Оно принимает функцию с одним или несколькими параметрами. Например:
.element {
transform: function1(parameter1, [...parameterN]);
}
Если требуется две или более трансформаций, можно указать несколько функций, разделенных пробелами:
.element {
transform: function1(p1, [...pN]) function2(p1, [...pN]);
}
Например, горизонтальное масштабирование и вертикальный сдвиг:
.element {
transform: scaleX(2) translateY(50px);
}
Правило transform: none
отменяет все существующие трансформации.
Функции сдвига
С помощью translate
-функций можно переместить элемент по горизонтали или по вертикали вдоль осей X и Y:
transform: translateX(50px); /* 50px вправо */
transform: translateY(-100%); /* 100% вверх */
transform: translate(50px, -100%); /* одновременно */
Можно использовать любые единицы измерения расстояния. Проценты будут отсчитываться от размеров самого элемента, таким образом, блок с высотой 100px функция при использовании translateY(80%)
будет сдвинут на 80px.
Для сдвига в третьем направлении существует translateZ
:
transform: translateZ(-200px); /* 200px вглубь экрана */
Возьмем три элемента – #box1
, #box2
и #box3
– и спозиционируем их абсолютно в одной точке. К #box
применим translateZ(-200px)
, а к #box3
– translate(-400px)
. Результат довольно скучный:
Повернем весь родительский контейнер #scene
по z-оси, чтобы понять, что происходит:
#scene {
transform-style: preserve-3d;
transform: rotateX(-10deg) rotateY(-10deg);
}
Функция translate3d
позволяет сдвинуть элемент по всем трем осям одновременно:
transform: translate3d(50px, 100%, 7em);
transform-style
По умолчанию (и всегда в IE), свойство transform-style
имеет значение flat
. Это означает, что все преобразованные дочерние элементы контейнера лежат в плоскости самого элемента. Другими словами, какую бы трансформацию вы не назначили, она не выйдет за двумерные рамки родителя.
В большинстве случаев transform-style: preserve-3d;
указывает, что дочерние элементы блока позиционируются в 3D-пространстве и все трансформации контейнера должны этому соответствовать.
Вращение
2D-функция rotate()
поворачивает элементы вокруг Z-оси и идентична rotateZ()
. Для примера:
transform: rotateZ(45deg); /* аналогичный эффект rotate(45deg) */
rotateX()
управляет вращением вокруг горизонтальной оси, а rotateY()
– вокруг вертикальной.
Угол вращения может быть определен несколькими способами:
turn
: например,0.5turn
– это половина оборота по часовой стрелке;deg
(градусы):90deg
– четверть оборота по часовой стрелке;rad
(радианы):-3.1416rad
– половина оборота против часовой стрелки;grad
(градианы): один полный оборот равен400grad
, таким образом,-200grad
– это четверть оборота против часовой стрелки;
Три оси вращения могут быть установлены функцией rotate3d()
. Немного путает то, что она принимает четыре параметра для определения вектора вращения:
x
– x-координата вектора, обозначающая ось вращения (0 или 1).y
– y-координата вектора, обозначающая ось вращения (0 или 1).z
– z-координата вектора, обозначающая ось вращения (0 или 1).a
– угол вращения. Положительное значение определяет поворот по часовой стрелке, а отрицательное – против.
Любители математики мазохисты могут ознакомиться с детальной документацией свойства rotate3d
на MDN.
Масштабирование
Функции scaleX()
и scaleY
растягивают или сжимают элемент по горизонтали или по вертикали соответственно.
transform: scaleX(2); /* ширина в 2 раза больше */
transform: scaleY(0.5); /* высота в 2 раза меньше */
scaleZ()
делает то же самое, но в глубину. В самом первом примере установка свойства transform: scaleZ(0.5)
уменьшит расстояние между квадратами в два раза.
Функция scale3d(x, y, z)
позволяет масштабировать сразу во всех направлениях:
#scene {
transform-style: preserve-3d;
transform: scale3d(2, 1, 0.5) rotateX(-10deg) rotateY(-10deg);
}
Центр трансформаций
По умолчанию элемент вращается и масштабируется относительно его центральной точки. Это поведение можно изменить, установив свойство transform-origin
с одним, двумя или тремя разделенными пробелами значениями:
- одно значение: смещение по x-оси. Может быть указано в единицах расстояния или процентах. Также можно использовать ключевые слова
left
,center
,right
,top
илиbottom
. Тутtop
иbottom
устанавливают y-смещение, а x при этом остается в центре. - два значения: смещение по x и y.
- три значения: смещение по x, y и z. Для последнего можно использовать только единицы длины (px, em).
Перемещение координаты по одной оси влияет на плоскости вращения по другим. Например, transform-origin: left center 0
; перемещает начало координат в центр левой грани. Это повлияет на функции rotateY()
и rotateZ()
.
Видимость задних граней
Задняя часть элемента отображается, когда он вращается вокруг оси x или y более чем на 90, но менее чем на 270 градусов в любом направлении. Задняя часть зеркально повторяет переднюю, и по умолчанию она видна (значение visible
).
Ее можно скрыть, установив backface-visibility: hidden;
:
#box2 {
backface-visibility: hidden;
}
#scene {
transform: rotateX(-10deg) rotateY(-135deg);
}
backface-visibility: hidden;
часто используется для анимации переворачивания карты, где два элемента обозначают переднюю и заднюю часть карты, но только один может быть виден в текущий момент.
Перспектива
Примеры, разобранные выше, не используют перспективу. Элемент, перемещенный глубже в плоскости z, остается того же размера, независимо от того, как далеко он находится от пользователя. По умолчанию свойство perspective
равно none
, но может иметь любое положительное значение. Например:
#scene {
perspective: 1000px;
transform: rotateX(-15deg) rotateY(-15deg);
}
Чем меньше длина перспективы, тем ближе точка схода и тем более выражен 3D-эффект:
#scene {
perspective: 200px;
transform: rotateX(-15deg) rotateY(-45deg);
}
Точка схода
По умолчанию точка схода перспективы находится в центре трансформируемого элемента. Его можно изменить, установив perspective-origin: x y;
, где:
x
– ключевое слово (left
, center
, right
) или процент от ширины элемента (значения 0%, 50% и 100% эквивалентны ключевым словам).y
– ключевое слово (top
, center
, bottom
) или процент от высоты элемента (значения 0%, 50% и 100% эквивалентны ключевым словам).
Точка схода в верхнем левом углу:
#scene {
perspective-origin: left top; /* or 0% 0% */
perspective: 1000px;
}
Точка схода в нижнем правом углу:
#scene {
perspective-origin: right bottom; /* or 100% 100% */
perspective: 1000px;
}
Кроме того, существует функция perspective()
– например, transform: perspective(200px)
. Однако, она, кажется, не учитывает perspective-origin
.
Все вместе
Масштабирование, вращение и сдвиг могут быть определены в одной функции matrix3d()
, которая требует не менее 16 значений для трехмерного аффинного преобразования.
Ее лучше всего использовать в JavaScript и только тем, кто хорошо разбирается в геометрии! В CSS удобнее и проще использовать простые функции преобразования.
Полезные ссылки
CSS-трансформации позволяют упростить манипуляции с объектам в трех измерениях. В интернете много потрясающих примеров 3D-преобразований, включая виртуальную реальность, шутеры от первого лица, галереи изображений и скользящий текст из Star Wars. Не все они могут использоваться в реальных проектах. Тем не менее, несколько изящных и плавных 3D-эффектов добавят на ваши страницы новое измерение реальности.
0 комментариев