Biến đổi các phần tử bằng các thuộc tính translate
, rotate
và scale
Thuộc tính CSS transform
Để áp dụng hành động chuyển đổi cho một phần tử, hãy sử dụng Thuộc tính CSS transform
. Cơ sở lưu trú chấp nhận một hoặc nhiều <transform-function>
, được áp dụng lần lượt.
.target {
transform: translateX(50%) rotate(30deg) scale(1.2);
}
Phần tử được nhắm mục tiêu được chuyển đổi trên trục X 50%, xoay 30 độ và cuối cùng tăng tỷ lệ lên 120%.
Mặc dù thuộc tính transform
hoạt động rất hiệu quả, nhưng sẽ hơi tẻ nhạt khi bạn muốn thay đổi từng giá trị trong số đó.
Để thay đổi tỷ lệ khi di chuột, bạn phải sao chép tất cả các hàm trong thuộc tính biến đổi, mặc dù các giá trị của chúng vẫn không thay đổi.
.target:hover {
transform: translateX(50%) rotate(30deg) scale(2); /* Only the value of scale() changed */
}
Các thuộc tính biến đổi riêng lẻ
Thông tin vận chuyển bằng Chrome 104 là các thuộc tính riêng để chuyển đổi CSS. Các thuộc tính là scale
, rotate
và translate
mà bạn có thể dùng để xác định riêng từng phần của phép biến đổi.
Bằng cách làm như vậy, Chrome sẽ kết hợp với Firefox và Safari đã hỗ trợ các thuộc tính này.
Bằng cách viết lại ví dụ transform
trước đó với các thuộc tính riêng lẻ, đoạn mã của bạn sẽ trở thành như sau:
.target {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
Các vấn đề về đơn đặt hàng
Một điểm khác biệt chính giữa thuộc tính transform
gốc của CSS và các thuộc tính mới là thứ tự áp dụng các hành động biến đổi đã khai báo.
Với transform
, các hàm biến đổi được áp dụng theo thứ tự viết từ trái (bên ngoài) sang phải (bên trong).
Với các thuộc tính biến đổi riêng lẻ, thứ tự không phải là thứ tự mà các thuộc tính đó được khai báo. Thứ tự luôn giống nhau: đầu tiên là translate
(bên ngoài), sau đó là rotate
và sau đó là scale
(bên trong).
Điều đó có nghĩa là cả hai đoạn mã sau đây đều cung cấp cùng một kết quả:
.transform--individual {
translate: 50% 0;
rotate: 30deg;
scale: 1.2;
}
.transform--individual-alt {
rotate: 30deg;
translate: 50% 0;
scale: 1.2;
}
Trong cả hai trường hợp, trước tiên, các phần tử được nhắm mục tiêu sẽ được 50%
dịch trên trục X, sau đó được xoay theo 30deg
và cuối cùng sẽ được điều chỉnh theo tỷ lệ 1.2
.
Nếu một trong các thuộc tính biến đổi riêng lẻ được khai báo cùng với thuộc tính transform
, thì các phép biến đổi riêng lẻ sẽ được áp dụng đầu tiên (translate
, rotate
và sau đó là scale
) với transform
cuối cùng (bên trong). Bạn có thể xem thêm thông tin chi tiết trong quy cách xác định cách tính ma trận biến đổi.
Hoạt ảnh
Lý do chính khiến các thuộc tính này được thêm vào là để tạo ảnh động dễ dàng hơn. Giả sử bạn muốn tạo ảnh động cho một phần tử như sau:
Sử dụng transform
Để triển khai ảnh động này bằng transform
, bạn phải tính toán tất cả các giá trị giữa cho mọi phép biến đổi đã xác định và đưa các giá trị đó vào mỗi khung hình chính. Ví dụ: để thực hiện xoay vòng ở mức 10%, bạn cũng phải tính toán giá trị của các phép biến đổi khác vì thuộc tính transform
cần tất cả giá trị đó.
Mã CSS thu được sẽ có dạng như sau:
@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;
}
Sử dụng các thuộc tính biến đổi riêng lẻ
Với các thuộc tính biến đổi riêng lẻ, việc viết các thuộc tính này trở nên dễ dàng hơn nhiều. Thay vì kéo tất cả các phép biến đổi từ khung hình chính vào khung hình chính, bạn có thể nhắm mục tiêu từng phép biến đổi. Bạn cũng không cần phải tính toán tất cả các giá trị ở giữa đó nữa.
@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;
}
Sử dụng các thuộc tính biến đổi riêng lẻ và một số khung hình chính
Để tạo mã theo mô-đun, bạn có thể chia mỗi ảnh động phụ thành một nhóm khung hình chính riêng.
@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;
}
Nhờ sự phân tách này, bạn có thể áp dụng từng nhóm khung hình chính riêng biệt theo ý muốn vì các thuộc tính transform
hiện đã trở thành các thuộc tính riêng lẻ và không còn ghi đè lên nhau nữa. Ở trên, bạn có thể đặt thời gian riêng cho mỗi phép biến đổi mà không cần phải viết lại toàn bộ.
Hiệu suất
Ảnh động sử dụng các thuộc tính mới này cũng hiệu quả như ảnh động của thuộc tính transform
hiện có.
Ảnh động của translate
, rotate
và scale
chạy trên trình tổng hợp giống như cách mà ảnh động của transform
chạy, vì vậy, chúng phù hợp với hiệu suất ảnh động theo cách tương tự như transform
.
Các thuộc tính mới này cũng hoạt động với thuộc tính will-change
. Nói chung, tốt nhất là tránh lạm dụng will-change
bằng cách sử dụng will-change
với số lượng phần tử tối thiểu cần thiết và trong khoảng thời gian ngắn nhất có thể. Tuy nhiên, bạn cũng nên càng cụ thể càng tốt. Ví dụ: nếu đang sử dụng will-change
để tối ưu hoá ảnh động với các thuộc tính rotate
và filter
, bạn nên khai báo điều này bằng cách sử dụng will-change: rotate, filter
. Cách này sẽ tốt hơn một chút so với việc sử dụng will-change: transform, filter
trong trường hợp bạn tạo ảnh động cho rotate
và filter
, vì một số cấu trúc dữ liệu mà Chrome tạo trước khi bạn sử dụng will-change
có sự khác biệt giữa transform
và rotate
.
Một phần của Loạt chương trình tương tác mới