CSS: Свойства трансформации translate, rotate и scale
CSS Свойство transform
Чтобы применить трансформацию/преобразования к элементу, используйте CSS Свойство transform
. Свойство принимает одну или несколько <transform-function>
которые применяются одно за другим.
.target {
transform: translateX(50%) rotate(30deg) scale(1.2);
}
Целевой элемент переместится на 50% по Оси X, повернётся на 30 градусов и масштабируется до 120%.
Хотя свойство transform
отлично работает, оно становиться немного утомительным, когда вы хотите изменить любое из этих значений по отдельности.
Для изменения масштабирования при наведении, вы должны продублировать все функции в свойстве transform
, даже если их значения остаются неизменными.
.target:hover {
transform: translateX(50%) rotate(30deg) scale(2); /* Изменяется только значение scale() */
}
Индивидуальные свойства трансформации
В Chrome 104 появились отдельные свойства для CSS transform
. Это свойства scale
, rotate
и translate
, которые можно использовать для индивидуального определения частей трансформации.
Тем самым Chrome присоединился к Firefox и Safari, которые уже поддерживали эти свойства.
Примечание: Не все функции трансформации имеют соответствующее индивидуальное свойство, например skewX()
и matrix()
.
Переписав предыдущий пример transform
с индивидуальными свойствами, сниппет станет таким:
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
Порядок имеет значение
Одним из ключевых различий между исходным CSS свойством transform
и новыми свойствами является порядок, в котором применяются объявленные свойства трансформации.
В transform
функции преобразования/трансформации применяются в порядке их написания — слева (снаружи) направо (внутрь).
С индивидуальными свойствами трансформации порядок преобразований не совпадает с порядком объявления. Порядок преобразования всегда один и тот же: первый translate
(снаружи), затем rotate
, а затем scale
(внутри).
Это значит, что оба следующих сниппета CSS кода дают одинаковый результат:
.transform--individual {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
.transform--individual-alt {
rotate: 30deg;
translate: 50% 0;
scale: 1.2;
}
В обоих случаях целевые элементы будут сначала перемещены на 50%
по Оси X, затем повёрнуты на 30deg
, и наконец масштабированы на 1.2
.
Если одно из индивидуальных свойств трансформации/преобразования объявлено вместе со свойством transform
, то сначала применяются индивидуальные преобразования (translate
, rotate
, и затем scale
), а transform
— последним (внутри). Более подробная информация содержится в спецификации, которая определяет, как должна быть рассчитана матрица преобразования.
Анимации
Основная причина, по который эти свойства были добавлены, состоит в том, чтобы упростить анимацию. Допустим вы хотите анимировать элемент следующим образом:
Использование transform
Чтобы реализовать эту анимацию с использованием transform
, вам нужно будет вычислить все промежуточные значения для всех определённых преобразований, и включить их в каждый ключевой кадр. Например, чтобы выполнить поворот на отметке 10%
, необходимо также рассчитать значения для других преобразований, потому что свойству transform
нужны все они.
Итоговый CSS код становится таким:
@keyframes anim {
0% { transform: translateX(0%); }
5% { transform: translateX(5%) rotate(90deg) scale(1.2); }
10% { transform: translateX(10%) rotate(180deg) scale(1.2); }
90% { transform: translateX(90%) rotate(180deg) scale(1.2); }
95% { transform: translateX(95%) rotate(270deg) scale(1.2); }
100% { transform: translateX(100%) rotate(360deg); }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
Использование индивидуальных свойств трансформации
С индивидуальными свойствами преобразования/трансформации становиться писать намного проще. Вместо того чтобы перетаскивать все трансформации/преобразования из одного ключевого кадра в другой, вы можете нацеливать каждое преобразование/трансформацию по отдельности. Также больше не нужно вычислять все эти промежуточные значения.
@keyframes anim {
0% { translate: 0% 0; }
100% { translate: 100% 0; }
0%, 100% { scale: 1; }
5%, 95% { scale: 1.2; }
0% { rotate: 0deg; }
10%, 90% { rotate: 180deg; }
100% { rotate: 360deg; }
}
.target {
animation: anim 2s;
animation-fill-mode: forwards;
}
Использование индивидуальных свойств преобразования и нескольких keyframes
Чтобы сделать ваш код модульным, вы можете разделить каждую вспомогательную анимацию на собственный набор ключевых кадров.
@keyframes move {
0% { translate: 0% 0; }
100% { translate: 100% 0; }
}
@keyframes scale {
0%, 100% { scale: 1; }
5%, 95% { scale: 1.2; }
}
@keyframes rotate {
0% { rotate: 0deg; }
10%, 90% { rotate: 180deg; }
100% { rotate: 360deg; }
}
.target {
animation: move 2s, scale 2s, rotate 2s;
animation-fill-mode: forwards;
}
Благодаря этому разделению вы можете применять каждый отдельный набор keyframes
по своему усмотрению, потому что свойства преобразования/трансформации, которые теперь стали отдельными свойствами, больше не перезаписывают друг друга. Кроме того, вы можете назначить каждому преобразованию разное время без необходимости переписывать их все.
Производительность
Анимации, использующие эти новые свойства, так же эффективны, как анимации с существующим свойством transform
.
Анимации translate
, rotate
, и scale
выполняются в компоновщике так же, как и анимации transform
, поэтому они также хороши для производительности анимации, как и transform
.
Эти новые свойства также хорошо работают со свойством will-change
. В общем, лучше избегать чрезмерного использования will-change
, применяя его к минимальному количеству необходимых элементов и в течении как можно более короткого промежутка времени. Но также хорошо быть как можно более конкретным. Например, если вы используете will-change
для оптимизации анимации со свойствами rotate
и filter
, вы должны объявить это с помощью will-change: rotate, filter
. Это намного лучше, чем использование will-change: transform, filter
, когда вы анимируете rotate
и filter
, потому что некоторые структуры данных, которые Chrome создаёт заранее, когда вы используете will-change
, отличаются для transform
от rotate
.