Hiệu ứng xuất hiện và biến mất là ảnh động được kích hoạt khi một phần tử xuất hiện hoặc biến mất khỏi khung nhìn. Bạn có thể dùng tính năng này để tạo trải nghiệm hấp dẫn và linh hoạt cho người dùng. Ví dụ: bạn có thể sử dụng hiệu ứng xuất hiện để làm mờ một phần tử khi phần tử đó xuất hiện trong khung nhìn hoặc hiệu ứng thoát để thu nhỏ phần tử đó khi phần tử đó ra khỏi khung nhìn.
Cách triển khai
Để thêm hiệu ứng xuất hiện và biến mất vào một phần tử, bạn cần kết hợp một vài thuộc tính CSS. Sau đây là hướng dẫn từng bước:
Tạo
@keyframesriêng biệt cho ảnh động vào cảnh và thoát cảnh. Ảnh động vào cảnh sẽ được áp dụng khi phần tử vào khung nhìn và ảnh động thoát cảnh sẽ được áp dụng khi phần tử rời khỏi khung nhìn.@keyframes slide-in { from { transform: translateX(-100%); } } @keyframes slide-out { to { transform: translateX(100%); } }Đính kèm khung hình chính vào và ra vào phần tử. Bạn có thể thực hiện việc này bằng cách xác định nhiều ảnh động trong thuộc tính
animation.- Cung cấp cho ảnh động vào cảnh một
animation-fill-modecủabackwardsđể áp dụng trạng thái ban đầu trước khi ảnh động bắt đầu. - Đặt
animation-fill-modecủa ảnh động thoát thànhforwardsđể ảnh động duy trì trạng thái cuối cùng sau khi hoàn tất.
.animated-element { animation: slide-in 1s linear backwards, slide-out 1s linear forwards; }- Cung cấp cho ảnh động vào cảnh một
Tạo một View Timeline và liên kết với ảnh động. Dòng thời gian của khung hiển thị là một loại dòng thời gian được liên kết với chế độ hiển thị của một phần tử trong khung nhìn. Bạn có thể tạo một bộ nội suy bằng hàm
view(), sau đó áp dụng bộ nội suy đó cho ảnh động bằng thuộc tínhanimation-timeline..animated-element { animation-timeline: view(); }Theo mặc định,
view()theo dõi phần tử trên trụcblock. Nếu cần theo dõi trên trụcinline, bạn có thể sử dụngview(inline).Giới hạn ảnh động trong phạm vi
entryvàexit. Thuộc tínhanimation-rangecho phép bạn chỉ định phần nào của dòng thời gian mà ảnh động sẽ chạy.- Phạm vi
entrybao gồm thời gian từ khi phần tử lần đầu tiên xuất hiện trong khung nhìn cho đến khi phần tử đó hiển thị đầy đủ. - Phạm vi
exitbao gồm thời gian từ khi phần tử bắt đầu rời khỏi khung nhìn cho đến khi phần tử đó bị ẩn hoàn toàn.
.animated-element { animation-range: entry, exit; }- Phạm vi
Mã mẫu
Mã này tạo ảnh động cho các phần tử con trực tiếp của trình cuộn khi cuộn bằng cách sử dụng view-timeline ẩn danh:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: view(inline);
animation-range: entry, exit;
}
}
}
Khi các phần tử đi vào khung nhìn cuộn, ảnh động grow sẽ được phát và khi các phần tử rời khỏi khung nhìn cuộn, ảnh động shrink sẽ được phát.
Đoạn mã sau đây có cùng kết quả hình ảnh, nhưng tạo ảnh động cho các phần tử con trực tiếp của trình cuộn khi cuộn bằng view-timeline được đặt tên:
@media (prefers-reduced-motion: no-preference) {
@supports ((animation-timeline: view()) and (animation-range: entry)) {
@keyframes grow {
from {
scale: 0.5;
}
}
@keyframes shrink {
to {
scale: 0.5;
}
}
.scroller > * {
view-timeline: --tl inline;
animation:
grow auto linear backwards,
shrink auto linear forwards;
animation-timeline: --tl;
animation-range: entry, exit;
}
}
}
Các phương pháp hay nhất
Khi sử dụng ảnh động dựa trên thao tác cuộn, bạn cần tuân thủ một số phương pháp hay nhất để đảm bảo trải nghiệm mượt mà và dễ tiếp cận:
- NÊN thêm tính năng phát hiện: Không phải trình duyệt nào cũng hỗ trợ ảnh động dựa trên thao tác cuộn. Sử dụng
@supports ((animation-timeline: view()) and (animation-range: entry))để kiểm tra khả năng hỗ trợ và cung cấp phương án dự phòng cho các trình duyệt không hỗ trợ.- BẮT BUỘC phải đưa quy trình kiểm tra
(animation-range: entry)vào đây để lọc ra những trình duyệt chỉ hỗ trợ một phần. - KHÔNG sử dụng gói
scroll-timeline-polyfillcho chiến lược dự phòng vì gói này chưa hoàn thiện tính năng và có nhiều vấn đề đã biết. - Nếu ảnh động chỉ được coi là để trang trí, hãy chọn Progressive Enhancement (Cải tiến tăng dần) và KHÔNG cung cấp phương án dự phòng.
- BẮT BUỘC phải đưa quy trình kiểm tra
- NÊN tôn trọng lựa chọn ưu tiên của người dùng: Một số người dùng muốn có ít chuyển động hơn trên web. Sử dụng truy vấn nội dung nghe nhìn
prefers-reduced-motionđể tắt hoặc giảm ảnh động cho những người dùng này. - NÊN cố gắng chỉ tạo ảnh động cho các thuộc tính CSS hiệu suất cao: Để có ảnh động mượt mà nhất, hãy chỉ tạo ảnh động cho các thuộc tính có thể được xử lý bằng luồng trình tổng hợp của trình duyệt, chẳng hạn như
transformvàopacity. Việc tạo ảnh động cho các thuộc tính khác nhưwidthhoặcheightcó thể dẫn đến các vấn đề về hiệu suất. - NÊN sử dụng đúng thứ tự khai báo: Khi sử dụng thuộc tính viết tắt
animation, hãy khai báoanimation-timelinesau thuộc tính đó để ngăn thuộc tính viết tắt đặt lại dòng thời gian.
Khi sử dụng hàm view() để tạo ảnh động dựa trên thao tác cuộn:
- KHÔNG BẮT BUỘC nêu rõ trục cần theo dõi: Khi không nhắm đến trục
blockmặc định (chẳng hạn như trong trình cuộn ngang), hãy nêu rõ trục cần theo dõi bằngview(block)hoặcview(inline). - Khi ảnh động không được áp dụng cho chính đối tượng được theo dõi, hãy sử dụng dòng thời gian của khung hiển thị được đặt tên.
Khi sử dụng thuộc tính view-timeline để tạo ảnh động dựa trên thao tác cuộn:
- NÊN sử dụng
<dashed-ident>CSS cho tên. - KHÔNG BẮT BUỘC nêu rõ trục cần theo dõi: Khi không nhắm đến trục
blockmặc định (chẳng hạn như trong trình cuộn ngang), hãy nêu rõ trục cần theo dõi bằngview-timeline-axis. - NÊN đảm bảo phạm vi của hoạt động tra cứu hoạt động: Khi phần tử khai báo
view-timelinekhông phải là phần tử cấp trên dạng cây phẳng của phần tử ảnh động, hãy nâng chế độ hiển thị tên củaview-timelinebằng cách sử dụngtimeline-scopetrên một phần tử cấp trên được chia sẻ.
Ưu tiên view-timeline được đặt tên khi nhiều phần tử hoặc phần tử con của đối tượng được theo dõi cần tạo ảnh động.
Hỗ trợ trình duyệt và chiến lược dự phòng
Do đó, bạn thường cần có một chiến lược dự phòng.
Đối với những trình duyệt không hỗ trợ ảnh động dựa trên thao tác cuộn, bạn có thể sử dụng tính năng dự phòng để tạo lại hiệu ứng hình ảnh. Các phương án dự phòng thường được xây dựng bằng trình nghe cuộn (cho hiệu ứng ScrollTimeline) hoặc API IntersectionObserver (cho hiệu ứng ViewTimeline).
Trong các trình duyệt có hỗ trợ tích hợp cho ảnh động dựa trên thao tác cuộn, hãy LUÔN sử dụng phương thức triển khai CSS gốc vì các trình duyệt đó có hiệu suất cao hơn.
Xin lưu ý rằng không phải hiệu ứng nào cũng có thể được tạo lại bằng phương pháp dự phòng.
Cụ thể cho trường hợp sử dụng này, tập lệnh sau đây áp dụng phương án dự phòng cho các trình duyệt không hỗ trợ ảnh động dựa trên thao tác cuộn. Hàm này sử dụng IntersectionObserver để theo dõi chế độ hiển thị của phần tử .wrapper và cập nhật thuộc tính transform của các lớp dựa trên vị trí cuộn.
<script>
if (!CSS.supports('(animation-timeline: view()) and (animation-range: entry)')) {
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
// This matches the effect as defined in the CSS example above.
// Customize this further if needed.
entry.target.style.scale = 0.5 + entry.intersectionRatio * 0.5;
}
},
{
threshold: Array.from({ length: 101 }, (_, i) => i / 100),
}
);
document.querySelectorAll('.scroller > *').forEach((el) => {
observer.observe(el);
});
}
</script>