Explore CSS Scroll-Driven Animations, the scroll() and view() timeline functions, binding animations to scrollport boundaries, and building high-performance 60fps parallax structures without JavaScript.

This lesson is currently only available in Vietnamese. Please switch the language toggle in the menu to Vietnamese to read the full guide and take the interactive quiz.

Trước đây, để tạo nên các hiệu ứng hoạt ảnh chạy theo trục cuộn (như thanh tiến trình đọc bài viết dài, parallax background, hoặc các hộp nội dung fade-in khi cuộn màn hình tới), lập trình viên bắt buộc phải sử dụng JavaScript bằng cách lắng nghe sự kiện window.addEventListener('scroll').

Cách làm truyền thống này là tác nhân cực kỳ nguy hiểm gây ra hiện tượng Layout Thrashing (tính toán lại bố cục liên tục) vì JavaScript chạy trên luồng chính (Main Thread), làm đứt gãy fps dưới 60fps. Để giải quyết triệt để, CSS hiện đại đã giới thiệu đặc tả đột phá: CSS Scroll-Driven Animations API, cho phép tạo các hoạt ảnh cuộn trang chạy trực tiếp ở mức phần cứng đồ họa (GPU Compositor Thread) vô cùng mượt mà.

1. Khái niệm Timeline mới: Time-based vs Scroll-based

Mặc định, các hoạt ảnh CSS truyền thống chạy trên một trục thời gian (Document Timeline). Thời gian trôi bao nhiêu giây thì hoạt ảnh chạy bấy nhiêu phần trăm.

Scroll-Driven Animation thay đổi trục thời gian này thành Scroll Progress Timeline (Trục tiến trình cuộn). Điểm bắt đầu cuộn tương ứng với 0% của hoạt ảnh, và điểm cuộn dưới cùng tương ứng với 100%. Hoạt ảnh sẽ tiến triển nhanh hay chậm hoàn toàn phụ thuộc vào tốc độ cuộn chuột của người dùng.

2. Hàm scroll(): Trục tiến trình cuộn của container

Hàm scroll() dùng để liên kết hoạt ảnh của phần tử với vị trí cuộn của một hộp chứa (scroll container).

Cú pháp khai báo cơ bản:

scroll.css
.progress-bar {
  width: 100%;
  transform-origin: left;
  animation: scale-x auto linear;
  /* Liên kết hoạt ảnh với hộp cuộn gần nhất theo trục dọc (Y) */
  animation-timeline: scroll(nearest y);
}
@keyframes scale-x {
  from { transform: scaleX(0); }
  to { transform: scaleX(1); }
}

Các tham số trong hàm scroll(scroller axis):

  • scroller: Đối tượng cuộn. Nhận nearest (hộp cuộn gần nhất), root (toàn bộ trang web), hoặc self (chính phần tử đó).
  • axis: Trục cuộn. Nhận y (cuộn dọc) hoặc x (cuộn ngang).

3. Hàm view() và Dải hoạt ảnh (Animation Range)

Nếu hàm scroll() liên kết với tiến trình cuộn của toàn bộ hộp chứa, thì hàm view() lại liên kết hoạt ảnh với độ hiển thị (visibility) của một phần tử cụ thể khi nó đi vào và đi ra khỏi vùng nhìn thấy của hộp cuộn (View Progress Timeline).

Cú pháp liên kết hoạt ảnh view:

view.css
.reveal-card {
  animation: fade-in-scale auto linear;
  animation-timeline: view(y);
  /* Điều khiển thời điểm kích hoạt hoạt ảnh */
  animation-range: entry 10% cover 50%;
}
🔬 Đào sâu: Giải thích các khoảng phạm vi Animation Range
Thuộc tính animation-range cực kỳ quan trọng để quy định thời điểm bắt đầu và kết thúc hoạt ảnh. Nó nhận các giá trị mốc phạm vi sau:
  • cover: Đại diện cho toàn bộ tiến trình từ khi mép trên của thẻ con bắt đầu chạm mép dưới của viewport (0%), cho đến khi mép dưới của thẻ con rời hẳn mép trên của viewport (100%).
  • contain: Đại diện cho tiến trình từ khi thẻ con lọt hoàn toàn vào trong viewport (0%), cho đến khi thẻ con bắt đầu chạm mép trên để rời đi (100%).
  • entry: Chỉ tính tiến trình thẻ con đi từ lúc chạm mép dưới của viewport cho đến khi lọt hẳn vào trong (thường dùng để làm hiệu ứng xuất hiện - Reveal).
  • exit: Chỉ tính tiến trình thẻ con bắt đầu chạm mép trên cho đến khi rời hẳn ra ngoài viewport (dùng để làm hiệu ứng biến mất).
📖 Tài liệu tham khảo & Hướng dẫn Scroll-Driven API
Để cập nhật đặc tả kỹ thuật và xem khả năng tương thích của Scroll-Driven Animations trên các trình duyệt, bạn có thể truy cập:

Sân chơi tương tác: Scroll-Driven Lab

Dưới đây là một mô hình giả lập thiết bị cuộn. Bạn có thể chọn loại hiệu ứng và cuộn chuột bên trong khung điện thoại để quan sát các hiệu ứng hoạt họa cuộn được tính toán mượt mà:

🎨 Sân chơi tương tác: Scroll-Driven Lab

Cấu hình Hoạt Ảnh

HERO PIC

Thẻ nội dung 1

Cuộn xuống để xem hiệu ứng...

Thẻ nội dung 2

CSS đang tự tính toán opacity.

Thẻ nội dung 3

Hoàn toàn không tốn CPU luồng chính.

Thẻ nội dung 4

GPU Composite xử lý hình học cực nhanh.

Thẻ nội dung 5

Cuộn ngược lên để đảo ngược hoạt ảnh.

Thẻ nội dung 6

Hộp nội dung cuối cùng.

scroll.html
<div class="viewport">
  <!-- Thanh tiến trình cuộn dọc -->
  <div class="progress-bar"></div>

  <div class="scroll-content">
    <!-- Ảnh Parallax đầu trang -->
    <div class="hero-header"></div>

    <!-- Các thẻ xuất hiện dần -->
    <div class="card">Thẻ 1</div>
    <div class="card">Thẻ 2</div>
  </div>
</div>
scroll.css

Trắc nghiệm ôn tập

Câu 1: Lợi thế cốt lõi lớn nhất khi sử dụng CSS Scroll-Driven Animations thay thế cho JS scroll listener là gì?

Trắc nghiệm ôn tập

Câu 2: Khoảng phạm vi (Animation Range) nào chỉ bắt đầu hoạt ảnh khi mép trên của phần tử con chạm mép dưới của viewport, và kết thúc khi con lọt hoàn toàn vào trong viewport?

Related Articles

Bài viết liên quan trong series

Lesson 8: View Transitions & Container Queries Bài 8: View Transitions & Container Queries — Morphing Trang & Tự Thích Ứng Lesson 6: Transform 2D/3D & Perspective — Graphics Space Bài 6: Transform 2D/3D & Perspective — Không Gian Đồ Họa 3 Chiều Back to CSS Course Overview Quay lại Lộ trình Series CSS