The CSS Podcast – 022: Ảnh động
Đôi khi, bạn sẽ thấy các trình trợ giúp nhỏ trên giao diện. Khi nhấp vào, các trình trợ giúp này sẽ cung cấp thông tin hữu ích về phần cụ thể đó. Các nút này thường có ảnh động nhấp nháy để cho bạn biết một cách tinh tế rằng thông tin đó có sẵn và bạn nên tương tác với thông tin đó. Mô-đun này hướng dẫn bạn cách tạo các trình trợ giúp đó và các ảnh động khác bằng CSS.
Bạn có thể sử dụng CSS để đặt trình tự ảnh động bằng các khung hình chính. Các trình tự này có thể là ảnh động cơ bản, một trạng thái hoặc trình tự phức tạp, dựa trên thời gian.
Khung hình chính là gì?
Trong hầu hết các công cụ tạo ảnh động, khung hình chính là cơ chế bạn sử dụng để gán trạng thái ảnh động cho dấu thời gian trên dòng thời gian.
Ví dụ: Dưới đây là tiến trình của dấu chấm "trợ giúp" nhấp nháy. Ảnh động chạy trong 1 giây và có 2 trạng thái.
Có một điểm cụ thể mà mỗi trạng thái ảnh động này bắt đầu và kết thúc. Bạn sẽ lập bản đồ các khung hình này trên dòng thời gian bằng các khung hình chính.
@keyframes
@keyframes
CSS dựa trên cùng một khái niệm với khung hình chính của ảnh động.
Sau đây là ví dụ về hai trạng thái:
@keyframes my-animation {
from {
transform: translateY(20px);
}
to {
transform: translateY(0px);
}
}
Phần quan trọng đầu tiên là mã nhận dạng tuỳ chỉnh (custom-ident
), tên của quy tắc khung hình chính. Giá trị nhận dạng trong ví dụ này là my-animation
.
Giá trị nhận dạng tuỳ chỉnh hoạt động như tên hàm, cho phép bạn tham chiếu quy tắc khung hình chính ở nơi khác trong mã CSS.
Bên trong quy tắc khung hình chính, from
và to
là các từ khoá đại diện cho 0%
và 100%
, là điểm bắt đầu và kết thúc của ảnh động.
Bạn có thể tạo lại quy tắc tương tự như sau:
@keyframes my-animation {
0% {
transform: translateY(20px);
}
100% {
transform: translateY(0px);
}
}
Bạn có thể thêm bao nhiêu vị trí tuỳ thích trong khung thời gian. Trong ví dụ về trình trợ giúp nhấp nháy, có hai trạng thái được chuyển thành hai khung hình chính. Điều này có nghĩa là bạn có hai vị trí bên trong quy tắc khung hình chính để thể hiện các thay đổi cho từng khung hình chính này.
@keyframes pulse {
0% {
opacity: 0;
}
50% {
transform: scale(1.4);
opacity: 0.4;
}
}
Thuộc tính animation
Để sử dụng @keyframes
trong quy tắc CSS, bạn có thể xác định từng thuộc tính ảnh động riêng lẻ hoặc sử dụng thuộc tính viết tắt animation
.
animation-duration
.my-element {
animation-duration: 10s;
}
Thuộc tính animation-duration xác định khoảng thời gian của tiến trình @keyframes
dưới dạng giá trị thời gian.
Giá trị mặc định là 0 giây, tức là ảnh động vẫn chạy nhưng sẽ quá nhanh để bạn có thể nhìn thấy. Bạn không thể sử dụng giá trị thời gian âm.
animation-timing-function
Để giúp tạo lại chuyển động tự nhiên trong ảnh động, bạn có thể sử dụng các hàm tính thời gian để tính toán tốc độ của ảnh động tại mỗi điểm. Các giá trị được tính toán thường cong, khiến ảnh động chạy ở tốc độ biến thiên trong quá trình animation-duration
và khiến phần tử có vẻ như bị nảy nếu trình duyệt tính toán một giá trị vượt quá các giá trị được xác định trong @keyframes
.
Có một số từ khoá có sẵn dưới dạng giá trị đặt trước trong CSS, được dùng làm giá trị cho animation-timing-function: linear
, ease
, ease-in
, ease-out
, ease-in-out
.
.my-element {
animation-timing-function: ease-in-out;
}
Giá trị hàm làm dịu có vẻ như cong vì được tính toán bằng đường cong Bézier, một loại hàm dùng để mô hình hoá tốc độ. Mỗi từ khoá hàm thời gian, chẳng hạn như ease
, tham chiếu đến một đường cong Bézier được xác định trước. Trong CSS, bạn có thể xác định trực tiếp một đường cong Bézier bằng cách sử dụng hàm cubic-bezier()
. Hàm này chấp nhận 4 giá trị số: x1
, y1
, x2
, y2
.
.my-element {
animation-timing-function: cubic-bezier(.42, 0, .58, 1);
}
Các giá trị này lập biểu đồ cho từng phần của đường cong dọc theo trục X và Y.
Việc hiểu đường cong Bézier rất phức tạp. Các công cụ trực quan, chẳng hạn như trình tạo này của Lea Verou, rất hữu ích.
Hàm làm mượt steps
Đôi khi, bạn có thể muốn kiểm soát ảnh động chi tiết hơn bằng cách di chuyển theo khoảng thời gian thay vì dọc theo một đường cong. Hàm easing (làm dịu) steps()
cho phép bạn chia dòng thời gian thành các khoảng thời gian được xác định có thời lượng bằng nhau.
.my-element {
animation-timing-function: steps(10, end);
}
Đối số đầu tiên là số bước. Nếu số lượng khung hình chính bằng số bước, thì mỗi khung hình chính sẽ phát theo trình tự trong khoảng thời gian chính xác của bước đó, không có chuyển đổi giữa các trạng thái. Nếu có ít khung hình chính hơn số bước, trình duyệt sẽ thêm các bước giữa các khung hình chính tuỳ thuộc vào đối số thứ hai.
Đối số thứ hai là hướng. Nếu bạn đặt giá trị này thành end
(giá trị mặc định), các bước sẽ kết thúc vào cuối tiến trình. Nếu bạn đặt giá trị này thành start
, thì bước đầu tiên của ảnh động sẽ hoàn tất ngay khi bắt đầu, tức là ảnh động sẽ kết thúc sớm hơn một bước so với end
.
animation-iteration-count
.my-element {
animation-iteration-count: 10;
}
Thuộc tính animation-iteration-count xác định số lần tiến trình @keyframes
sẽ chạy trong ảnh động. Theo mặc định, giá trị này là 1, nghĩa là ảnh động sẽ dừng khi đến cuối dòng thời gian. Giá trị này không được là số âm.
Để tạo vòng lặp ảnh động, hãy đặt số lần lặp thành infinite
. Đây là cách hoạt động của ảnh động nhấp nháy ở đầu bài học này.
animation-direction
.my-element {
animation-direction: reverse;
}
Bạn có thể đặt hướng chạy của tiến trình trên các khung hình chính bằng thuộc tính animation-direction. Thuộc tính này có các giá trị sau:
normal
: giá trị mặc định là chuyển tiếp.reverse
: chạy ngược trên dòng thời gian.alternate
: đối với mỗi lần lặp ảnh động, tiến trình sẽ luân phiên giữa việc chạy tiến và chạy lùi.alternate-reverse
: Giống nhưalternate
, nhưng ảnh động bắt đầu bằng tiến trình chạy ngược.
animation-delay
.my-element {
animation-delay: 5s;
}
Thuộc tính animation-delay xác định khoảng thời gian trình duyệt chờ trước khi bắt đầu ảnh động.
Giống như thuộc tính animation-duration
, thuộc tính này chấp nhận giá trị thời gian.
Không giống như animation-duration
, bạn có thể xác định animation-delay
là một giá trị âm, giúp ảnh động bắt đầu tại điểm tương ứng trong tiến trình. Ví dụ: nếu ảnh động của bạn dài 10 giây và bạn đặt animation-delay
thành -5s
, thì ảnh động sẽ bắt đầu từ giữa dòng thời gian.
animation-play-state
.my-element:hover {
animation-play-state: paused;
}
Thuộc tính animation-play-state cho phép bạn phát và tạm dừng ảnh động.
Giá trị mặc định là running
. Nếu bạn đặt giá trị này thành paused
, ảnh động sẽ tạm dừng.
animation-fill-mode
Thuộc tính animation-fill-mode xác định những giá trị trong tiến trình @keyframes
của bạn sẽ tồn tại trước khi ảnh động bắt đầu hoặc sau khi ảnh động kết thúc. Giá trị mặc định là none
, nghĩa là khi ảnh động hoàn tất, các giá trị trong tiến trình của bạn sẽ bị loại bỏ.
Các lựa chọn khác bao gồm:
forwards
: Khung hình chính cuối cùng vẫn tồn tại, dựa trên hướng ảnh động.backwards
: Khung hình chính đầu tiên vẫn tồn tại, dựa trên hướng ảnh động.both
: Cả khung hình chính đầu tiên và cuối cùng đều tồn tại.
Chữ viết tắt animation
Thay vì xác định từng thuộc tính riêng biệt, bạn có thể xác định các thuộc tính đó theo viết tắt animation
. Điều này cho phép bạn xác định các thuộc tính ảnh động theo thứ tự sau:
animation-name
animation-duration
animation-timing-function
animation-delay
animation-iteration-count
animation-direction
animation-fill-mode
animation-play-state
.my-element {
animation: my-animation 10s ease-in-out 1s infinite forwards forwards running;
}
Những điều cần cân nhắc khi làm việc với ảnh động
Người dùng có thể đặt hệ điều hành của họ thành ưu tiên giảm chuyển động khi tương tác với các ứng dụng và trang web. Bạn có thể phát hiện lựa chọn ưu tiên này bằng cách sử dụng truy vấn nội dung đa phương tiện prefers-reduced-motion:
@media (prefers-reduced-motion) {
.my-autoplaying-animation {
animation-play-state: paused;
}
}
Đây không nhất thiết là lựa chọn ưu tiên không sử dụng ảnh động. Đây là lựa chọn ưu tiên cho ít ảnh động, đặc biệt là ít ảnh động không mong muốn. Bạn có thể tìm hiểu thêm về tuỳ chọn ưu tiên này và hiệu suất tổng thể trong hướng dẫn về ảnh động của chúng tôi.
Kiểm tra mức độ hiểu biết
Kiểm tra kiến thức của bạn về ảnh động
Tên hoặc giá trị nhận dạng tuỳ chỉnh của ảnh động @keyframes
có phân biệt chữ hoa chữ thường không?
SWOOP
và swoop
cùng tồn tại.Từ khoá from
và to
giống với:
start
và end
.0%
và 100%
.from
giống với 0%
và to
giống với 100%.0
và 1
animation-timing-function
cũng thường được gọi là:
Số lượng khung hình chính tối thiểu cần có bên trong ảnh động @keyframes
là bao nhiêu?