TL;DR
Thuộc tính CSS overscroll-behavior cho phép nhà phát triển ghi đè hành vi cuộn tràn mặc định của trình duyệt khi đến đầu/cuối nội dung. Các trường hợp sử dụng bao gồm tắt tính năng kéo để làm mới trên thiết bị di động, xoá hiệu ứng phát sáng khi cuộn quá mức và hiệu ứng dải cao su, đồng thời ngăn nội dung trang cuộn khi nội dung đó nằm bên dưới một lớp phủ/phương thức.
Thông tin khái quát
Ranh giới cuộn và chuỗi cuộn
Thao tác cuộn là một trong những cách cơ bản nhất để tương tác với một trang, nhưng một số mẫu trải nghiệm người dùng có thể khó xử lý do hành vi mặc định kỳ lạ của trình duyệt. Ví dụ: hãy xem xét một ngăn chứa ứng dụng có số lượng lớn mục mà người dùng có thể phải di chuyển qua. Khi người dùng cuộn đến cuối, vùng chứa mục bổ sung sẽ ngừng cuộn vì không còn nội dung nào để xem. Nói cách khác, người dùng đã chạm đến "ranh giới cuộn". Nhưng hãy lưu ý điều gì sẽ xảy ra nếu người dùng tiếp tục cuộn. Nội dung phía sau ngăn kéo bắt đầu cuộn! Thao tác cuộn được vùng chứa gốc đảm nhận; chính là trang chính trong ví dụ.
Hoá ra hành vi này được gọi là chuỗi cuộn; hành vi mặc định của trình duyệt khi cuộn nội dung. Thường thì giá trị mặc định khá tốt, nhưng đôi khi không như mong muốn hoặc thậm chí không mong đợi. Một số ứng dụng có thể muốn cung cấp trải nghiệm người dùng khác khi người dùng chạm đến ranh giới cuộn.
Hiệu ứng kéo để làm mới
Kéo để làm mới là một cử chỉ trực quan được các ứng dụng di động như Facebook và Twitter phổ biến. Thao tác kéo xuống trên nguồn cấp dữ liệu trên mạng xã hội rồi thả ra sẽ tạo không gian mới để tải các bài đăng gần đây hơn. Trên thực tế, trải nghiệm người dùng cụ thể này đã trở nên rất phổ biến đến mức các trình duyệt di động như Chrome trên Android cũng áp dụng hiệu ứng tương tự. Thao tác vuốt xuống ở đầu trang sẽ làm mới toàn bộ trang:
khi làm mới một nguồn cấp dữ liệu trong PWA của họ.
sẽ làm mới toàn bộ trang.
Đối với các trường hợp như PWA của Twitter,
bạn nên tắt thao tác kéo để làm mới gốc. Tại sao? Trong ứng dụng này, có thể bạn không muốn người dùng vô tình làm mới trang. Bạn cũng có thể thấy ảnh động làm mới hai lần! Ngoài ra, bạn nên tuỳ chỉnh thao tác của trình duyệt để phù hợp hơn với thương hiệu của trang web. Điều đáng tiếc là loại tuỳ chỉnh này rất khó thực hiện. Nhà phát triển phải viết JavaScript không cần thiết, thêm trình nghe thao tác chạm không thụ động (chặn thao tác cuộn) hoặc dán toàn bộ trang vào một <div> 100vw/vh (để ngăn trang bị tràn). Những giải pháp này có tác động tiêu cực đã được ghi nhận đến hiệu suất cuộn.
Chúng ta có thể làm tốt hơn!
Xin giới thiệu overscroll-behavior
Thuộc tính overscroll-behavior là một tính năng CSS mới giúp kiểm soát hành vi xảy ra khi bạn cuộn quá mức một vùng chứa (bao gồm cả chính trang đó). Bạn có thể sử dụng thuộc tính này để huỷ chuỗi cuộn, tắt/tuỳ chỉnh thao tác kéo để làm mới, tắt hiệu ứng dải cao su trên iOS (khi Safari triển khai overscroll-behavior) và nhiều thao tác khác.
Điều tuyệt vời nhất là việc sử dụng overscroll-behavior không ảnh hưởng xấu đến hiệu suất trang như các thủ thuật được đề cập trong phần giới thiệu!
Thuộc tính này có thể nhận 3 giá trị:
- auto – Mặc định. Thao tác cuộn bắt nguồn từ phần tử có thể truyền đến các phần tử cấp trên.
- contain – ngăn chặn việc cuộn theo chuỗi. Thao tác cuộn không truyền đến các thành phần cấp trên nhưng hiệu ứng cục bộ trong nút sẽ xuất hiện. Ví dụ: hiệu ứng phát sáng khi cuộn quá mức trên Android hoặc hiệu ứng dải cao su trên iOS thông báo cho người dùng khi họ chạm đến ranh giới cuộn. Lưu ý: việc sử dụng
overscroll-behavior: containtrên phần tửhtmlsẽ ngăn các thao tác điều hướng cuộn quá mức. - none – giống như
containnhưng cũng ngăn chặn hiệu ứng cuộn quá mức trong chính nút đó (ví dụ: hiệu ứng phát sáng khi cuộn quá mức trên Android hoặc hiệu ứng dải cao su trên iOS).
Hãy cùng tìm hiểu một số ví dụ để biết cách sử dụng overscroll-behavior.
Ngăn thao tác cuộn thoát khỏi phần tử có vị trí cố định
Tình huống hộp trò chuyện
Hãy xem xét một hộp trò chuyện có vị trí cố định nằm ở cuối trang. Mục đích là để hộp trò chuyện trở thành một thành phần độc lập và cuộn riêng biệt với nội dung phía sau. Tuy nhiên, do tính năng cuộn theo chuỗi, tài liệu sẽ bắt đầu cuộn ngay khi người dùng nhấn vào tin nhắn cuối cùng trong nhật ký trò chuyện.
Đối với ứng dụng này, việc giữ cho các thao tác cuộn bắt nguồn từ trong hộp trò chuyện ở lại trong cuộc trò chuyện sẽ phù hợp hơn. Chúng ta có thể thực hiện việc đó bằng cách thêm
overscroll-behavior: contain vào phần tử chứa tin nhắn trò chuyện:
#chat .msgs {
overflow: auto;
overscroll-behavior: contain;
height: 300px;
}
Về cơ bản, chúng tôi đang tạo ra sự phân tách logic giữa bối cảnh cuộn của hộp trò chuyện và trang chính. Kết quả cuối cùng là trang chính vẫn giữ nguyên khi người dùng đến đầu/cuối nhật ký trò chuyện. Thao tác cuộn bắt đầu trong hộp trò chuyện sẽ không được truyền ra ngoài.
Trường hợp lớp phủ trang
Một biến thể khác của trường hợp "cuộn bên dưới" là khi bạn thấy nội dung cuộn phía sau một lớp phủ vị trí cố định. Một món quà miễn phí
overscroll-behavior đang chờ bạn! Trình duyệt đang cố gắng giúp ích nhưng
cuối cùng lại khiến trang web trông có vẻ lỗi.
Ví dụ – phương thức có và không có overscroll-behavior: contain:
Tắt tính năng kéo để làm mới
Bạn có thể tắt thao tác kéo để làm mới bằng một dòng CSS duy nhất. Chỉ cần ngăn chặn
chuỗi cuộn trên toàn bộ phần tử xác định khung nhìn. Trong hầu hết các trường hợp, đó là <html> hoặc <body>:
body {
/* Disables pull-to-refresh but allows overscroll glow effects. */
overscroll-behavior-y: contain;
}
Với nội dung bổ sung đơn giản này, chúng ta sẽ khắc phục được hiệu ứng kéo để làm mới kép trong bản minh hoạ hộp trò chuyện và thay vào đó, có thể triển khai hiệu ứng tuỳ chỉnh sử dụng ảnh động tải gọn gàng hơn. Toàn bộ hộp thư đến cũng mờ đi khi hộp thư đến làm mới:
Dưới đây là một đoạn mã của mã đầy đủ:
<style>
body.refreshing #inbox {
filter: blur(1px);
touch-action: none; /* prevent scrolling */
}
body.refreshing .refresher {
transform: translate3d(0,150%,0) scale(1);
z-index: 1;
}
.refresher {
--refresh-width: 55px;
pointer-events: none;
width: var(--refresh-width);
height: var(--refresh-width);
border-radius: 50%;
position: absolute;
transition: all 300ms cubic-bezier(0,0,0.2,1);
will-change: transform, opacity;
...
}
</style>
<div class="refre>she<r"
div class=&qu><ot;l>oad<ing-bar"/div
div>< cla>ss=<"loading-bar"></div>
<div class="loading><-bar>&<quot>;/<div
div class=&q><uot;loading><-bar&quo>t;</div
/>div
section id="inbox"!-- msgs --/section
script
let _startY;
const inbox = document.querySel>ector('#inbox');
inbox.addEventListener('touchstart', e = {
_startY = e.touches>[0].pageY;
}, {passive: true});
inbox.addEventListener('touchmove', e = {
const y = e.touches[0].pageY;
// Activate custom pull-to-refresh effects when at the top of the container&&
> // and &&user is scrolling up.
if (document.scrollingElement.scrollTop === 0 y _startY
!document.body.class<List.co>ntains('refreshing')) {
// refresh inbox.
}
}, {passive: true});
/script
Tắt hiệu ứng phát sáng và hiệu ứng dải cao su khi cuộn quá mức
Để tắt hiệu ứng nảy khi chạm vào ranh giới cuộn, hãy sử dụng overscroll-behavior-y: none:
body {
/* Disables pull-to-refresh and overscroll glow effect.
Still keeps swipe navigations. */
overscroll-behavior-y: none;
}
Bản minh hoạ đầy đủ
Tóm lại, bản minh hoạ hộp trò chuyện đầy đủ sử dụng overscroll-behavior để tạo ảnh động kéo để làm mới tuỳ chỉnh và ngăn thao tác cuộn thoát khỏi tiện ích hộp trò chuyện. Điều này mang lại trải nghiệm tối ưu cho người dùng mà nếu không có CSS overscroll-behavior thì sẽ rất khó đạt được.