Tổng quan
Các gợi ý trực quan, chẳng hạn như bóng hoặc dải chuyển màu, giúp người dùng hiểu rằng họ có thể di chuyển để xem thêm nội dung. Hướng dẫn này trình bày cách tạo các gợi ý này bằng CSS container-scroll-state-queries. CSS này cho phép tạo kiểu cho các phần tử dựa trên trạng thái có thể cuộn của vùng chứa mà không cần dựa vào trình quan sát hoặc trình nghe cuộn JavaScript.
Triển khai
1. Thiết lập vùng chứa cuộn
Vùng chứa cuộn phải được khai báo là vùng chứa truy vấn trạng thái cuộn.
.scroller {
overflow-y: auto;
/* Establish this element as a scroll-state query container */
container-type: scroll-state;
position: relative;
}
2. Tạo kiểu cho chỉ báo
Đặt các phần tử chỉ báo (như bóng, dải chuyển màu hoặc mũi tên) bên trong vùng chứa và tạo kiểu cho các phần tử đó. Theo mặc định, các thành phần này không được hiển thị. Khi được hiển thị, các mục này không được có tính tương tác, bằng cách đặt pointer-events: none.
.indicator-top, .indicator-bottom {
position: sticky;
left: 0;
right: 0;
height: 20px;
opacity: 0;
transition: opacity 0.2s;
pointer-events: none; /* Let clicks pass through */
}
.indicator-top {
top: 0;
background: linear-gradient(to bottom, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}
.indicator-bottom {
bottom: 0;
background: linear-gradient(to top, rgba(0,0,0,0.2), transparent); /* Example: Shadow */
}
3. Truy vấn trạng thái cuộn
Sử dụng quy tắc @container với hàm scroll-state. Kiểm tra xem vùng chứa có thể cuộn lên hoặc xuống để hiển thị chỉ báo tương ứng hay không.
/* Show top indicator when the user can scroll up */
@container scroll-state(scrollable: top) {
.indicator-top {
opacity: 1;
}
}
/* Show bottom indicator when the user can scroll down */
@container scroll-state(scrollable: bottom) {
.indicator-bottom {
opacity: 1;
}
}
Chiến lược dự phòng
Dự phòng cơ bản
Nếu tính năng này không được hỗ trợ, các chỉ báo sẽ vẫn ở trạng thái ẩn. Vì đây là gợi ý và không quan trọng đối với chức năng, nên bạn có thể bỏ qua các gợi ý này trong những trình duyệt không được hỗ trợ.
Dự phòng nâng cao (Intersection Observer)
Nếu cần có gợi ý, hãy sử dụng IntersectionObserver để bật/tắt các lớp khi các phần tử canh lề ở đầu và cuối thanh cuộn di chuyển vào và ra khỏi khung nhìn cuộn.
<!-- Sentinel elements placed at the ends of the scroller -->
<div class="sentinel-top"></div>
<!-- Content goes here -->
<div class="sentinel-bottom"></div>
/* Marker styling to ensure it does not affect layout */
.sentinel-top, .sentinel-bottom {
height: 0;
width: 0;
visibility: hidden;
}
.scroller.scrolled-down .indicator-top {
opacity: 1;
}
.scroller.can-scroll-down .indicator-bottom {
opacity: 1;
}
if (!CSS.supports('container-type', 'scroll-state')) {
const topSentinel = document.querySelector('.sentinel-top');
const bottomSentinel = document.querySelector('.sentinel-bottom');
const scroller = document.querySelector('.scroller');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.target === topSentinel) {
// If top sentinel is not intersecting, we have scrolled down
scroller.classList.toggle('scrolled-down', !entry.isIntersecting);
}
if (entry.target === bottomSentinel) {
// If bottom sentinel is intersecting, we reached the bottom
scroller.classList.toggle('can-scroll-down', !entry.isIntersecting);
}
});
}, { root: scroller });
observer.observe(topSentinel);
observer.observe(bottomSentinel);
}