Kaydırarak gösterme kalıpları, kullanıcıların ön plandaki bir satırı veya içerik bölmesini yatay olarak kaydırarak gizli kullanıcı arayüzünü (ör. Sabitle, Sessize al, Arşivle, Sil gibi bağlamsal işlem düğmeleri veya ikincil bir yan menü) herhangi bir işlemi otomatik olarak etkinleştirmeden göstermesine olanak tanır. Kaydırma sırasında bir işlem yapmak yerine kapsayıcı, kullanıcının inceleyip etkinleştirebileceği veya kapatmak için geri kaydırabileceği etkileşimli kontrolleri göstermek için açılır.
Bir öğeyi anında işleyen ve bir eşiği geçtikten sonra kapatan tam genişlikte kaydırma hareketi için Kaldırmak için kaydır bölümüne bakın. Dikey kaydırma kapsayıcısının üst kısmındaki gizli başlığı göstermek için Çekerek Gösterme bölümüne bakın.
Nasıl uygulanır?
İster bir liste öğesindeki işlem düğmelerini ister kaydırılabilir bir bölmenin yanındaki yan menüyü gösteriyor olun, mekanikler aynıdır: Ön plan içeriğini ve gizli paneli, CSS kaydırarak tutturma (scroll-snap-type: x mandatory) ve overscroll-behavior: chain ile yapılandırılmış harici bir yatay kaydırma kapsayıcısına sarmalayın. Tarayıcının yerel kaydırma motoru; momentum, yakalama, klavye odağı kaydırma ve kaydırma zincirleme işlemlerini JavaScript hareket dinleyicileri olmadan gerçekleştirir.
1. adım: Kaydırma sarmalayıcıyı, içeriği ve gösterilen paneli işaretleyin
.SwipeReveal kaydırma kapsayıcısının içine önce ön plan içeriğini, ardından gösterilen kontrolleri (işlem düğmeleri veya yan menü) yerleştirin. İçerik, DOM sırasında ilk sırada olduğundan kaydırma kapsayıcısı doğal olarak 0 kaydırma ofsetinde başlar ve panel, ekranın sağ tarafında gizlenir.
<!-- Example A: List item with revealable action buttons -->
<div class="SwipeReveal">
<div class="SwipeReveal-content">
<strong>Design review notes</strong>
<p>Updated component specs for the Q3 release.</p>
</div>
<div class="SwipeReveal-panel" role="group" aria-label="Item actions">
<button type="button">Pin</button>
<button type="button">Archive</button>
<button type="button">Delete</button>
</div>
</div>
<!-- Example B: Scrollable content pane with a revealable side menu -->
<div class="SwipeReveal" role="region" aria-label="Document preview with swipeable side menu">
<div class="SwipeReveal-content is-scrollable" tabindex="0">
<h2>Article Preview</h2>
<p>Scroll vertically through this pane, or swipe left to reveal the side menu...</p>
</div>
<nav class="SwipeReveal-panel" aria-label="Contextual menu">
<a href="#share">Share</a>
<a href="#bookmark">Bookmark</a>
<a href="#export">Export PDF</a>
</nav>
</div>
2. adım: Yatay tutturma kapsayıcısını ve overscroll-behavior: chain öğesini yapılandırın
Bir öğeyi yalnızca kaydırarak gösterme efekti oluşturmak için dış kaydırma kapsayıcısına sarmaladığınızda, bu dış sarmalayıcı dokümanın (veya başka bir üst kaydırma kapsayıcısının) içinde bir ara kaydırıcı olur.
overscroll-behavior özelliğinin dört anahtar kelimesi, fazla kaydırmanın bir üst kaydırma kapsayıcısına yayılıp yayılmayacağını (kaydırma zinciri) ve kapsayıcının, elastik lastik bant esnetme veya kenar parlaklığı gibi yerel kaydırma sonu olanaklarını (yerel sınır efekti) gösterip göstermeyeceğini bağımsız olarak kontrol eder:
| Değer | Kaydırma Zincirleme (Üst Öğeye Yayılır) | Yerel Sınır Efekti (Lastik Bant/Işıma) | Kaydırarak Gösterme'deki rolü |
|---|---|---|---|
auto |
Evet | Evet | Varsayılan davranış; normal geri sekme geri bildiriminin istendiği iç içerik kaydırıcılarında bu ayarı etkin tutun ancak menünün geri sekmesine neden olduğu dış kaydırma sarmalayıcısında bu ayarı devre dışı bırakın. |
chain |
Evet | Hayır | Menü veya işlem şeridi sıçramadan, fazla kaydırmanın üst kaydırıcıya (ör. doküman) zincirlenmesi için dış .SwipeReveal kaydırıcıda kullanın |
contain |
Hayır | Evet | Yerel olarak sıçramaya devam ederken kaydırmayı kapsayıcı içinde yakalar. |
none |
Hayır | Hayır | Hem yerel sıçramayı hem de üst öğelere kaydırma zincirini engeller. |
.SwipeReveal öğesini, .SwipeReveal-content öğesinin start öğesine ve .SwipeReveal-panel öğesinin end öğesine uyarlandığı iki sütunlu bir tablo (grid-template-columns: 100% max-content) haline getirin:
.SwipeReveal {
/* Column 1: full-width content. Column 2: auto-sized actions or side menu. */
display: grid;
grid-template-columns: 100% max-content;
overflow-x: auto;
scroll-snap-type: x mandatory;
scrollbar-width: none;
/* Prevent the swipe wrapper and revealed panel from bouncing locally while
still chaining excess scroll into the parent scroller (the document). */
overscroll-behavior: chain;
}
@media (prefers-reduced-motion: no-preference) {
.SwipeReveal {
scroll-behavior: smooth;
}
}
.SwipeReveal-content {
scroll-snap-align: start;
scroll-initial-target: nearest;
background: Canvas;
}
.SwipeReveal-content:focus-visible {
outline: auto;
outline-offset: -2px;
}
.SwipeReveal-content.is-scrollable {
block-size: 20rem;
overflow: auto;
/* Keeps default `overscroll-behavior: auto` so the content pane retains
its normal bounce effect while chaining horizontal swipes to `.SwipeReveal`. */
}
.SwipeReveal-panel {
/* Snapping a trailing panel to `end` (or a leading panel to `start`) brings
all controls fully into view while keeping the adjacent edge of the content visible. */
scroll-snap-align: end;
display: flex;
&:first-child {
scroll-snap-align: start;
}
}
Üç sütun (
grid-template-columns: max-content 100% max-content) veya iki sütun (max-content 100%) kullanarak sol taraftaki (inline-start) kontrolleri de göstermek istiyorsanız baştaki.SwipeReveal-panelöğesini.SwipeReveal-contentöğesinden önce yerleştirin..SwipeReveal-content,scroll-initial-target: nearestdeğerine sahip olduğundan kaydırma kapsayıcısı başlangıçta ön panel yerine içerik sütununda yer alır.
3. adım: Odaklanabilir içerik bölmelerini klavye odağına geri getirin
.SwipeReveal-panel içindeki düğmeler veya bağlantılar ekran dışında olduğundan, klavyeyle sekme tuşuna basarak bunlara geçildiğinde .SwipeReveal otomatik olarak kaydırılarak odaklanılan kontrol gösterilir. Ancak .SwipeReveal-content, dış kapsayıcının genişliğinin 100% kadarını kapladığından, yan panel açıkken bile büyük bir kısmı kaydırma alanının içinde kalır. Bu nedenle, odağı tekrar .SwipeReveal-content öğesine (veya içindeki odaklanabilir bir öğeye) taşımak için Shift+Tab tuşuna basıldığında parça otomatik olarak 0 konumuna geri kaydırılmaz.
.SwipeReveal-content üzerinde focusin için dinleyin ve event.target.matches(':focus-visible') öğesini kontrol edin. Böylece, bölmedeki veya herhangi bir alt öğedeki klavye odağı, işaretçi tıklamalarına veya dokunarak sürüklemelere müdahale etmeden .SwipeReveal-content öğesini başlangıca geri döndürür:
for (const content of document.querySelectorAll('.SwipeReveal-content')) {
content.addEventListener('focusin', (event) => {
if (event.target.matches(':focus-visible')) {
content.scrollIntoView({
block: 'nearest',
inline: 'start',
});
}
});
}
En iyi uygulamalar ve tuzaklar
proximityyerinescroll-snap-type: x mandatoryKULLANIN.proximityile hafifçe kaydırdığınızda işlem düğmeleri veya yan menü kısmen açık kalabilir.- YAPIN: Kaydırma işleminin, gösterilen menü veya işlem şeridi sıçramadan üst kaydırıcıya zincirlenebilmesi için dış yatay kaydırarak gösterme kaydırıcısında (
.SwipeReveal)overscroll-behavior: chaindeğerini ayarlayın. - YAPIN: Yatay kaydırmaları dış kaydırıcıya zincirlerken normal geri sekme geri bildiriminin gerçekleşmesini istediğiniz iç kaydırılabilir içerik bölmelerinde (
.SwipeReveal-content.is-scrollable)overscroll-behavior: auto(varsayılan) değerini bırakın. - DO implement revealed actions and side-menu items as real focusable DOM controls (
<button>,<a>). When.SwipeReveal-contentis focusable or contains focusable controls, pair afocusinlistener withevent.target.matches(':focus-visible')to callscrollIntoView({ block: 'nearest', inline: 'start' })so tabbing back into the content pane closes the side panel without affecting pointer interactions. - İçeriği manuel olarak çevirmek veya kaydırma zincirini taklit etmek için JavaScript'te
wheel,touchmoveveyapointermoveetkinliklerini kesintiye UĞRATMAYIN. Ana iş parçacığı hareket müdahalesi, birleştirici tarafından yönlendirilen kaydırmayı engeller, yerel kaydırma momentumunu bozar ve yanıt verme hızını düşürür.
Fallback
Bir .SwipeReveal kapsayıcısı, .SwipeReveal-content öğesinden önce sol (inline-start) tarafa bir .SwipeReveal-panel yerleştirdiğinde, scroll-initial-target: nearest özelliğini desteklemeyen tarayıcılar başlangıçta, baştaki panel açık olacak şekilde 0 kaydırma ofsetinde oluşturulur.
Baseline hedefiniz scroll-initial-target özelliğini desteklemiyorsa CSS.supports('scroll-initial-target', 'nearest') ile desteği algılayın ve load üzerinde behavior: 'instant' ile scrollTo() yöntemini çağırın. Böylece, başta panel içeren kapsayıcılar sayfayı kaydırmadan doğrudan .SwipeReveal-content özelliğine atlar:
Progresif geliştirme
overscroll-behavior: chain ve scrollbar-width: none öğelerini JavaScript yedekleri olmadan progresif geliştirmeler olarak değerlendirin:
- Otomatik CSS basamaklı yedek:
overscroll-behavioriçin ilk değerauto.chainanahtar kelimesini henüz tanımayan tarayıcılar, ayrıştırma sırasındaoverscroll-behavior: chaindeğerini yoksayar veautodeğerini korur.auto, üst kaydırma kapsayıcılarına kaydırma zincirlemesine zaten izin verdiğinden, hem kaydırarak gösterme hareketi hem de üst öğeye kaydırma zincirleme, tüm tarayıcılarda kullanıma hazır olarak çalışır. Destekleyen tarayıcılar, dış kaydırma sarmalayıcısındaki istenmeyen lastik bant sıçramasını bastırır. containveyanonedeğerini geçersiz kılma: Temel bir stil sayfası veya yardımcı sınıfoverscroll-behavior: containya danonedeğerini ayarlıyorsaoverscroll-behavior: chaindeğerinden hemen önceoverscroll-behavior: autodeğerini tanımlayın. Böylece, henüzchaindeğerini desteklemeyen tarayıcılar kaydırmayı yakalamak yerine üst öğeye zincirlemeye devam eder.- Kaydırma çubuğunu gizleme (
scrollbar-width: none): Yatay kaydırma çubuğu yolunu gizlemek tamamen görsel bir işlemdir. Eski bir motorscrollbar-width: noneözelliğini yoksayarsa kaydırarak gösterme kapsayıcısı, standart bir kaydırma çubuğuyla tam olarak çalışmaya devam eder.