CSS: Свойства трансформации translate, rotate и scale

Источник: «Finer grained control over CSS transforms with individual transform properties»
Более детальный контроль над 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 нужны все они.

Анимация, использование 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;
}

See the Pen

Использование индивидуальных свойств трансформации

С индивидуальными свойствами преобразования/трансформации становиться писать намного проще. Вместо того чтобы перетаскивать все трансформации/преобразования из одного ключевого кадра в другой, вы можете нацеливать каждое преобразование/трансформацию по отдельности. Также больше не нужно вычислять все эти промежуточные значения.

@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;
}

See the Pen

Использование индивидуальных свойств преобразования и нескольких 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;
}

See the Pen

Благодаря этому разделению вы можете применять каждый отдельный набор 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.

Дополнительные материалы

Предыдущая Статья

Новое в Symfony 6.3 — Улучшения login и logout

Следующая Статья

Новое в Symfony 6.3 — Сопоставитель параметров запроса