Chấm dứt kỷ nguyên web giật lag
Các nhà phát triển web từng phải nỗ lực rất nhiều để làm cho quá trình chuyển trang trở nên mượt mà. Chúng ta thường làm nặng bundle bằng các thư viện hơn 30KB như Framer Motion hay GSAP chỉ để tạo hiệu ứng cho một thay đổi DOM đơn giản. Sau khi triển khai View Transitions API trong nhiều dự án thực tế suốt sáu tháng qua, tôi thấy nó giúp cắt giảm gần 70% mã nguồn cho hiệu ứng. Tính năng trình duyệt gốc này mang lại sự linh hoạt như ứng dụng di động mà không gây ra nợ kỹ thuật từ việc quản lý vòng đời phức tạp.
Làm chủ API này không còn là tùy chọn đối với các công việc frontend cao cấp. Nó thu hẹp khoảng cách giữa web và ứng dụng di động gốc, biến những cú nhảy trang rời rạc thành những chuyển động điện ảnh tinh tế, giúp người dùng luôn giữ được định hướng.
Bắt đầu nhanh: Hiệu ứng đầu tiên trong 5 phút
Về cốt lõi, View Transitions API dựa trên phương thức document.startViewTransition(). Bạn truyền vào một hàm callback để cập nhật DOM, và trình duyệt sẽ lo phần còn lại. Nó chụp ảnh trạng thái hiện tại, chờ cập nhật, chụp ảnh trạng thái mới, và sau đó thực hiện hiệu ứng cross-fade giữa chúng.
Dưới đây là một triển khai tinh gọn cho ứng dụng Single Page Application (SPA):
function updateDOMContent() {
const container = document.querySelector('#content');
container.innerHTML = '<h1>Nội dung trang mới</h1>';
}
// Kích hoạt chuyển cảnh với kiểm tra tính năng
if (document.startViewTransition) {
document.startViewTransition(() => updateDOMContent());
} else {
updateDOMContent();
}
Khi đoạn mã này chạy, trình duyệt sẽ tạo ra hiệu ứng cross-fade mượt mà trong 300ms theo mặc định. Không cần thư viện CSS hay định nghĩa keyframe. Trình duyệt chụp ảnh “trước”, thực thi logic của bạn, chụp ảnh “sau”, và tạo hiệu ứng chuyển động giữa hai ảnh chụp tĩnh này.
Đi sâu tìm hiểu: Cấu trúc Pseudo-Element của trình duyệt
Để đi xa hơn các hiệu ứng mờ dần đơn giản, bạn cần hiểu cách trình duyệt biểu diễn quá trình chuyển cảnh. Khi bạn gọi startViewTransition, trình duyệt sẽ tạo ra một cây pseudo-element tạm thời nằm trên nội dung của bạn. Cây này cho phép bạn truy cập trực tiếp các trạng thái chuyển cảnh bằng CSS.
::view-transition: Lớp bao ngoài cùng (top-level wrapper).::view-transition-group(root): Container quản lý kích thước và vị trí.::view-transition-old(root): Ảnh chụp tĩnh của trạng thái trước khi thay đổi.::view-transition-new(root): Ảnh chụp của trạng thái sau khi thay đổi.
Bạn có thể nhắm mục tiêu vào các phần tử này để tinh chỉnh cảm giác của trang web. Nếu bạn muốn hiệu ứng ease-in-out kéo dài 1 giây thay vì cross-fade nhanh mặc định, bạn có thể áp dụng các thuộc tính CSS tiêu chuẩn trực tiếp vào các pseudo-element này:
::view-transition-old(root),
::view-transition-new(root) {
animation-duration: 1s;
animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
Vì các hiệu ứng này được tăng tốc phần cứng bởi bộ tổng hợp (compositor) của trình duyệt, chúng luôn duy trì mức 60fps ổn định. Hiệu năng này rất khó đạt được khi thao tác DOM thủ công bằng JavaScript.
Sử dụng nâng cao: Biến đổi phần tử và hỗ trợ MPA
Trường hợp sử dụng ấn tượng nhất là “Hero Pattern”. Đây là khi một phần tử nhỏ, như ảnh thu nhỏ 150px, dường như lớn dần và di chuyển thành một banner hero 1080p ở trang tiếp theo. Chúng ta đạt được điều này bằng thuộc tính view-transition-name.
Hiệu ứng Hero
Gán một cái tên khớp nhau cho các phần tử ở cả trang nguồn và trang đích. Điều này báo cho trình duyệt biết chúng là cùng một thực thể logic.
/* Trên danh sách sản phẩm */
.product-card-img {
view-transition-name: product-hero;
}
/* Trên trang chi tiết sản phẩm */
.product-detail-banner {
view-transition-name: product-hero;
}
Trình duyệt tính toán sự khác biệt giữa vị trí và kích thước của hai phần tử. Sau đó, nó tự động nội suy chuyển động. Những gì trước đây yêu cầu toán học phức tạp và định vị tuyệt đối (absolute positioning) giờ đây chỉ cần hai dòng CSS.
Ứng dụng đa trang (MPA)
View Transitions giờ đây không chỉ dành cho các ứng dụng React hay Vue. Kể từ Chrome 126, bạn có thể bật chuyển cảnh cho các ứng dụng đa trang (MPA) truyền thống—như những ứng dụng được xây dựng với WordPress, Django hoặc Rails—chỉ bằng CSS. Thêm quy tắc này vào stylesheet toàn cục của bạn:
@view-transition {
navigation: auto;
}
Khi nhấp vào một liên kết trên trang web, trình duyệt sẽ kích hoạt hiệu ứng cross-fade gốc giữa các tài liệu. Nó ngay lập tức khiến một trang web cũ mang lại cảm giác hiện đại, hiệu năng cao như một ứng dụng web mà không tốn thêm chi phí JavaScript.
Bài học thực tế từ thực địa
Triển khai tính năng này trong môi trường production đã hé lộ một số sắc thái không phải lúc nào cũng rõ ràng trong tài liệu.
1. Tôn trọng độ nhạy chuyển động
Không phải người dùng nào cũng muốn màn hình của họ trượt đi trượt lại. Hãy tôn trọng media query prefers-reduced-motion để đảm bảo khả năng truy cập cho người dùng bị rối loạn tiền đình. Sử dụng một ghi đè đơn giản để tắt hiệu ứng khi được yêu cầu.
@media (prefers-reduced-motion: reduce) {
::view-transition-group(*),
::view-transition-old(*),
::view-transition-new(*) {
animation: none !important;
}
}
2. Đặt tên động cho danh sách
Nếu bạn có một lưới gồm 50 mục, bạn không thể đặt cho tất cả chúng cùng một view-transition-name vì hiệu ứng sẽ bị lỗi. Thay vào đó, hãy áp dụng tên một cách động khi người dùng nhấp vào. Điều này đảm bảo trình duyệt chỉ theo dõi phần tử cụ thể đang chuyển cảnh.
function handleItemClick(e) {
// Gán tên chuyển cảnh động cho mục được click
e.target.style.viewTransitionName = 'active-item';
document.startViewTransition(() => {
updateUI();
});
}
3. Chờ dữ liệu
Hàm callback startViewTransition hỗ trợ các hàm bất đồng bộ. Nếu bạn cần lấy dữ liệu từ API trước khi hiển thị trang mới, trình duyệt sẽ giữ trạng thái “cũ” cho đến khi Promise của bạn được giải quyết. Điều này ngăn chặn hiện tượng “nháy nội dung trống” làm hỏng trải nghiệm người dùng.
4. Sử dụng Animations Inspector
Tinh chỉnh các chuyển cảnh này sẽ dễ dàng hơn nhiều với các công cụ phù hợp. Trong Chrome DevTools, hãy mở ngăn **Animations**. Nó cho phép bạn làm chậm quá trình chuyển cảnh xuống 10%, tạm dừng giữa chừng và kiểm tra các pseudo-element để xem chính xác lý do tại sao một phép biến đổi (transform) có thể bị cắt hoặc lệch.
View Transitions API thay đổi căn bản việc điều phối UI từ nhà phát triển sang trình duyệt. Bằng cách bắt đầu với các hiệu ứng mờ dần cơ bản và dần dần thêm các phần tử hero, bạn có thể xây dựng các giao diện mang lại cảm giác cao cấp và trau chuốt mà không gặp phải các vấn đề về hiệu năng thông thường.

