Ниже приведен небольшой отрывок из новой книги Тиффани « Мастер CSS», 2-е издание .
Преобразования позволяют нам создавать эффекты и взаимодействия, которые в противном случае невозможны. В сочетании с переходами и анимацией мы можем создавать элементы и интерфейсы, которые вращаются, танцуют и масштабируются. В частности, трехмерные преобразования позволяют имитировать физические объекты. В этой части мы рассмотрим функции 2D-преобразования ( 3D-функции описаны здесь ).
Существует четыре основных функции двумерного преобразования: rotate
, scale
, skew
и translate
. Шесть других функций позволяют преобразовать элемент в одном измерении: scaleX
и scaleY
; skewX
и skewY
; и translateX
и translateY
.
rotate()
Преобразование вращения вращает элемент вокруг его начала на угол, заданный вокруг точки начала transform-origin
. Использование rotate()
наклоняет элемент по часовой стрелке (положительные значения угла) или против часовой стрелки (отрицательные значения угла). Его эффект очень похож на ветряную мельницу или вертушку, как показано ниже.
Функция rotate()
принимает значения в угловых единицах. Угловые единицы определяются модулем «Значения и единицы измерения CSS» уровня 3 . Это могут быть градусы (градусы), rad
(радианы), градусы (градианы) или единицы turn
. Один полный оборот равен 360deg
6.28rad
, 400grad
6.28rad
, 400grad
или 1 1turn
.
Значения поворота, которые превышают одно вращение (скажем, 540deg
или 1.5turn
), отображаются в соответствии с их 1.5turn
значением, если они не анимированы или не переведены. Другими словами, 540 градусов отображается так же, как 180deg
градусов (540 градусов минус 360 градусов), а 1.5turn
— так же, как .5turn
(1,5 — 1). Но переход или анимация от 0 0deg
до 540deg
или от 1turn
до 1.5turn
будет вращать элемент в полтора раза.
Функции 2D масштабирования: scale
, scale
scaleY
и scaleY
С помощью функций масштабирования мы можем увеличить или уменьшить визуализированный размер элемента в X-измерении ( scaleX
), Y-измерении ( scaleY
) или в обоих ( scale
). Масштабирование показано ниже, где граница иллюстрирует исходные границы прямоугольника, а знак + обозначает его центральную точку.
Каждая функция масштаба принимает множитель или коэффициент в качестве аргумента. Этот множитель может быть примерно любым положительным или отрицательным числом. Значения в процентах не поддерживаются. Положительные множители больше 1
увеличивают размер элемента. Например, scale(1.5)
увеличивает размер элемента в направлениях X и Y в 1,5 раза. Положительные множители от 0
до 1
уменьшат размер элемента.
Значения меньше 0
также приведут к увеличению или уменьшению размера элемента и созданию преобразования отражения (отражения).
Предупреждение: использование scale(0)
приведет к исчезновению элемента, поскольку умножение числа на ноль приводит к произведению нуля.
Использование scale(1)
создает преобразование идентичности , что означает, что оно отображается на экране, как будто преобразование масштабирования не применялось. Использование scale(-1)
не изменит нарисованный размер элемента, но отрицательное значение приведет к отражению элемента. Даже если элемент не выглядит преобразованным, он все равно запускает новый контекст стека и содержит блок.
Можно масштабировать размеры X и Y отдельно, используя функцию scale
. Просто передайте ему два аргумента: scale(1.5, 2)
. Первый аргумент масштабирует X-измерение; второй масштабирует Y-размерность. Мы могли бы, например, отразить объект вдоль оси X, используя scale(-1, 1)
. Передача одного аргумента масштабирует оба измерения одним и тем же фактором.
Функции 2D-перевода: translateX
, translateY
и translate
Перевод элемента смещает его закрашенное положение от положения макета на указанное расстояние. Как и в случае с другими преобразованиями, трансляция элемента не меняет его offsetLeft
или offsetTop
. Это, однако, влияет на то, где оно визуально расположено на экране.
Каждая функция 2D-перевода — translateX
, translateY
и translate
принимает длины или проценты для аргументов. Единицы длины включают пиксели ( px
), em
, rem
и единицы просмотра ( vw
и vh
).
Функция translateX
изменяет горизонтальную позицию рендеринга элемента. Если элемент расположен на нулевом transform: transitionX(50px)
слева, transform: transitionX(50px)
смещает свою визуализированную позицию на 50 пикселей вправо от своей начальной позиции. Точно так же translateY
изменяет вертикальную позицию рендеринга элемента. Transform of transform: transitionY(50px)
смещает элемент по вертикали на 50 пикселей.
С translate()
мы можем сместить элемент по вертикали и горизонтали, используя одну функцию. Он принимает до двух аргументов: значение перевода X и значение перевода Y. На рисунке ниже показано влияние элемента со значением transform
translate(120%, -50px)
, где левый зеленый квадрат находится в исходном положении, а правый зеленый квадрат переводится на 120% по горизонтали и -50px по вертикали от его содержащий элемент (пунктирная граница).
Передача одного аргумента для translate
является эквивалентом использования translateX
; значение перевода Y будет установлено на 0
. Использование translate()
является более кратким вариантом. Применение translate(100px, 200px)
эквивалентно translateX(100px) translateY(200px)
.
Положительные значения перевода перемещают элемент вправо (для translateX
) или вниз (для translateY
). Отрицательные значения перемещают элемент влево ( translateX
) или вверх ( translateY
).
Переводы особенно хороши для перемещения предметов влево, вправо, вверх или вниз. Обновление значений свойств left
, right
, top
и bottom
заставляет браузер пересчитывать информацию макета для всего документа. Но преобразования рассчитываются после расчета макета. Они влияют на то, где элементы появляются на экране, но не на их фактические размеры. Да, странно думать о макете и рендеринге документа как об отдельных концепциях, но с точки зрения браузеров это так.
Свойства преобразования могут появиться в браузере рядом с вами
Последняя версия спецификации CSS Transforms добавляет свойства translate
, rotate
и scale
в CSS. Свойства преобразования работают так же, как и соответствующие им функции преобразования, но значения разделяются пробелами, а не запятыми. Мы могли бы, например, выразить transform: rotate3d(1, 1, 1, 45deg)
используя свойство rotate: 1 1 1 45deg
. Аналогично, translate: 15% 10% 300px
визуально совпадает с transform: translate3d(15%, 10%, 300px)
и scale: 1.5 1.5 3
аналогично transform: scale3d(1.5, 1.5, 3)
. С помощью этих свойств мы можем управлять преобразованиями вращения, перемещения или масштабирования отдельно от других преобразований.
На момент написания, поддержка браузером свойств преобразования все еще довольно скудна. Chrome и Samsung Интернет поддерживают их из коробки. В Firefox версии 60 и выше поддержка скрыта за флагом; посетите about: config
и установите для layout.css.individual-transform.enabled
значение true
.
skew
, skewX
и skewY
Косые преобразования смещают углы и расстояния между точками, сохраняя их в одной плоскости. Косые преобразования также известны как сдвиговые преобразования , и они искажают формы элементов, как показано ниже, где пунктирная линия представляет исходную ограничивающую рамку элемента.
Функции перекоса — skew
, skewX
и skewY
принимают большинство угловых единиц в качестве аргументов. Градусы, градианы и радианы являются действительными угловыми единицами для функций перекоса, в то время как единицы поворота, возможно, очевидно, не являются.
Функция skewX
элемент в X или горизонтальном направлении (см. Изображение ниже). Он принимает один параметр, который снова должен быть угловой единицей. Положительные значения смещают элемент влево, а отрицательные значения смещают его вправо.
Точно так же, skewY
сдвигает элемент в Y или вертикальном направлении. На изображении ниже показан эффект transform: skewY(30deg)
. Точки справа от начала координат смещены вниз с положительными значениями. Отрицательные значения сдвигают эти точки вверх.
Это подводит нас к функции skew
. Функция skew
требует один аргумент, но принимает до двух. Первый аргумент наклоняет элемент в направлении X, а второй — в направлении Y. Если указан только один аргумент, предполагается, что второе значение равно нулю, что делает его эквивалентным искажению только в направлении X. Другими словами, skew(45deg)
отображает то же самое, что skewX(45deg)
.
Матрица преобразования тока
До сих пор мы обсуждали функции преобразования отдельно, но их также можно комбинировать. Хотите масштабировать и вращать объект? Нет проблем: используйте список преобразования . Например:
.rotatescale { transform: rotate(45deg) scale(2); }
Это дает результаты, которые вы видите ниже.
Порядок имеет значение при использовании функций преобразования. Этот момент лучше показать, чем обсуждать, поэтому давайте рассмотрим пример для иллюстрации. Следующий CSS наклоняет и поворачивает элемент:
.transformEl { transform: skew(10deg, 15deg) rotate(45deg); }
Это дает нам результат, который вы видите ниже.
Что произойдет, если сначала повернуть элемент, а затем наклонить его?
.transformEl { transform: rotate(45deg) skew(10deg, 15deg); }
Эффект, показанный ниже, совершенно другой.
Каждое из этих преобразований имеет различную текущую матрицу преобразования, созданную в соответствии с порядком ее функций преобразования. Чтобы полностью понять, почему это так, нам нужно немного изучить матричное умножение . Это также поможет нам понять функции matrix
и matrix3d
.
Умножение матриц и функции матриц
Матрица — это массив чисел или выражений, расположенных в прямоугольнике строк и столбцов. Все преобразования могут быть выражены с использованием матрицы 4 × 4, как показано ниже.
Эта матрица соответствует функции matrix3d
, которая принимает 16 аргументов, по одному для каждого значения матрицы 4 × 4. Двумерные преобразования также могут быть выражены с использованием матрицы 3 × 3, как показано ниже.
Эта матрица 3 × 3 соответствует функции преобразования matrix
. Функция matrix()
принимает шесть параметров, по одному для значений от a до f .
Каждая функция преобразования может быть описана с использованием матрицы и функций matrix
или matrix3d
. На рисунке ниже показана матрица 4 × 4 для функции scale3d
, где sx , sy и sz — коэффициенты масштабирования для размеров X, Y и Z соответственно.
Когда мы объединяем преобразования — такие как transform: scale(2) translate(30px, 50px)
— браузер умножает матрицы для каждой функции, чтобы создать новую матрицу. Эта новая матрица — это то, что применяется к элементу.
Но вот в чем заключается умножение матриц: оно не коммутативно. При простых значениях произведение 3 × 2 совпадает с 2 × 3. Однако в случае матриц произведение A × B не обязательно совпадает с произведением B × A. Давайте посмотрим на пример. Мы рассчитаем матричный продукт transform: scale(2) translate(30px, 50px)
.
Наш элемент был масштабирован в два раза, а затем переведен на 60 пикселей по горизонтали и 100 пикселей по вертикали. Мы также можем выразить этот продукт, используя matrix
функцию: transform: matrix(2, 0, 0, 2, 60, 100)
. Теперь давайте переключим порядок этих преобразований, то есть transform: translate(30px, 50px) scale(2)
. Результаты показаны ниже.
Обратите внимание, что наш объект все еще масштабируется в два раза, но здесь он переводится на 30 пикселей по горизонтали и 50 пикселей по вертикали. Выражается с помощью функции matrix
, это transform: matrix(2, 0, 0, 2, 30, 50)
.
Также стоит отметить, что унаследованные преобразования работают аналогично спискам преобразования. Каждое дочернее преобразование умножается на любое преобразование, примененное к его родителю. Например, возьмите следующий код:
<div style="transform: skewX(25deg)"> <p style="transform: rotate(-15deg)"></p> </div>
Это отображается так же:
<div> <p style="transform: skewX(25deg) rotate(-15deg)"></p> </div>
Текущая матрица преобразования элемента p
будет одинаковой в обоих случаях. Хотя до сих пор мы фокусировались на 2D-преобразованиях, вышесказанное относится и к 3D-преобразованиям. Третье измерение добавляет иллюзию глубины. Это также приносит некоторую дополнительную сложность в виде новых функций и свойств.