Göstermek için kaydırın

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: nearest değ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

  • proximity yerine scroll-snap-type: x mandatory KULLANIN. proximity ile 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: chain değ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-content is focusable or contains focusable controls, pair a focusin listener with event.target.matches(':focus-visible') to call scrollIntoView({ 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, touchmove veya pointermove etkinliklerini 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-behavior için ilk değer auto. chain anahtar kelimesini henüz tanımayan tarayıcılar, ayrıştırma sırasında overscroll-behavior: chain değerini yoksayar ve auto değ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.
  • contain veya none değerini geçersiz kılma: Temel bir stil sayfası veya yardımcı sınıf overscroll-behavior: contain ya da none değerini ayarlıyorsa overscroll-behavior: chain değerinden hemen önce overscroll-behavior: auto değerini tanımlayın. Böylece, henüz chain değ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 motor scrollbar-width: none özelliğini yoksayarsa kaydırarak gösterme kapsayıcısı, standart bir kaydırma çubuğuyla tam olarak çalışmaya devam eder.