Kaydırma durumu kapsayıcı sorguları, öğeleri mevcut kaydırma durumlarına göre (ör. bir öğenin "sıkışmış" (yapışkan konumlandırma yoluyla) veya "tutturulmuş" (kaydırarak tutturma yoluyla) olup olmadığına göre) stillendirmenize olanak tanır. Bu sayede, JavaScript kesişim gözlemcilerine veya kaydırma etkinliği işleyicilerine gerek kalmadan, etkin öğenin görsel olarak ayırt edilebildiği bant veya galeri deneyimleri sunulabilir.
Temel uygulama
Tutturulan öğeleri vurgulamak için bir kaydırarak tutturma kapsayıcısı oluşturmanız, tutturma hedeflerini kaydırma durumu kapsayıcıları olarak tanımlamanız ve ardından alt öğeleri stillendirmek için bu durumu sorgulamanız gerekir.
1. Kaydırarak tutturma kapsayıcısını oluşturma
Üst kapsayıcıda scroll-snap-type etkinleştirilmelidir.
<div class="carousel">
<div class="carousel-item">
<div class="card">Product 1 content</div>
</div>
<div class="carousel-item">
<div class="card">Product 2 content</div>
</div>
</div>
.carousel {
display: flex;
overflow-x: auto;
/* MANDATORY: Enable scroll snapping on the container */
scroll-snap-type: x mandatory;
}
2. Kaydırma hedefi öğelerini kaydırma durumu kapsayıcıları olarak tanımlama
Durdurma için izlenmesi gereken her öğe, bantta scroll-state kapsayıcısı olarak tanımlanmalıdır.
.carousel-item {
/* Define where the item snaps within the container */
scroll-snap-align: center;
/* MANDATORY: Establish this element as a scroll-state query container */
container-type: scroll-state;
}
3. snapped durumunu sorgulama
Kapsayıcı sorguları alt öğeleri biçimlendirdiği için vurgulama stillerini, yakalama hedefinin içindeki bir öğeye uygulamanız gerekir. Kaydırma kapsayıcısı, x ekseninde taşacak şekilde ayarlandığından scroll-state(snapped: x) sorgusunu kullanın.
ZORUNLU: Efekti yalnızca daha az hareket talep etmeyen kullanıcılara göstermek için stilleri @media (prefers-reduced-motion: no-preference) içine alın. Kullanım alanınıza bağlı olarak efektin bazı kısımlarını koruyabilirsiniz ancak bu durumda kartlar beyazdan maviye doğru yanıp söner. Bu durum bazı kullanıcılar için sorunlara neden olabileceğinden efekti tamamen devre dışı bırakıyoruz.
/* Specify transition outside of queries so that it is applied regardless of state. */
.card {
transition:
scale 0.4s cubic-bezier(0.25, 0.8, 0.25, 1),
background-color 0.4s,
color 0.4s,
box-shadow 0.4s;
}
/*
Only show the effect for users not requesting reduced motion. Disable completely, including the color change, as it causes a flash that may be problematic.
*/
@media (prefers-reduced-motion: no-preference) {
/* Style the content when its parent .carousel-item is snapped on the x axis */
@container scroll-state(snapped: x) {
.card {
background: #007bff;
color: white;
scale: 1.15;
box-shadow: 0 10px 25px rgba(0, 123, 255, 0.3);
}
}
}
/* MANDATORY Copy-Paste Safety: Disable highlight scaling/flashing for motion sensitive users */
@media (prefers-reduced-motion: reduce) {
.card {
transition: none !important;
scale: 1 !important;
}
}
snapped tanımlayıcısı belirli eksenleri sorgulayabilir: x, y, inline, block veya both.
Erişilebilirlik
AVOID: Etkileşimli öğelerle scroll-state kullanmaktan kaçının.
Tutturulan öğeler için görsel vurgular kullanıcı deneyimini iyileştirebilir ancak tutturulan öğe, erişilebilirlik ağacına gösterilmez. Tutturulan bir öğeye uygulanan görsel tema, öğenin etkin veya odaklanmış olduğunu göstermemeli ve klavye odak halkası, snapped vurgusundan net bir şekilde ayırt edilebilmelidir. Tutturulan öğe etkileşimliyse erişilebilir hale getirmek için diğer standart erişilebilirlik uygulamalarını kullanmanız gerekir.
Kaydırma işlemi nedeniyle gerçekleşen tutturma, klavye odağını değiştirmez. Ancak klavye odağı, kaydırma kapsayıcısının hareket etmesine neden olarak sabitlenen öğede değişikliğe yol açabilir. Bu öğe, odaklanılan öğe olabilir veya olmayabilir. Bu durum, kullanıcıların kafasını karıştırabilir ve önerilmez.
Yedek stratejiler
Kaydırma durumu sorgularını desteklemeyen tarayıcılar için, "etkin" vurgusu olmasa bile tüm öğelerin okunabilir olduğu işlevsel bir temel deneyim sunmanız gerekir.
Özellik algılama
Yalnızca desteklenen tarayıcılarda iyileştirme sağlamak için @supports kullanabilirsiniz:
@supports (container-type: scroll-state) {
/* Enhancement styles here */
}
JavaScript yedek
Vurgu, kullanıcı deneyimi için kritik öneme sahipse yakalanan öğeyi belirlemek için IntersectionObserver kullanın. Negatif satır içi değere sahip bir rootMargin sağlayarak gözlemlenen alanı, bandın ortasındaki ince bir dilime ayarlayın. Örneğin, bir öğenin bandın ortasındaki% 2'lik dilimde yer alması durumunda kesiştiğini kabul etmek için rootMargin değerini "0px -49%" olarak ayarlayın.
// Optional: detect support and apply a JS-based fallback
if (!CSS.supports('container-type', 'scroll-state')) {
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
// Toggle a class based on intersection
entry.target.classList.toggle('is-snapped', entry.isIntersecting);
});
}, {
root: document.querySelector(".carousel"),
// Carousel item intersects if any part of the carousel item is in the middle 2% of the carousel.
rootMargin: "0px -49%"
});
document.querySelectorAll('.carousel-item').forEach(item => {
observer.observe(item);
});
}