Pociągnij, aby wyświetlić

„Przeciągnij, aby wyświetlić” to wzorzec interfejsu, w którym treść (np. pasek wyszukiwania lub element sterujący odświeżaniem) jest ukryta nad górną krawędzią obszaru przewijania podczas początkowego wczytywania, a użytkownik może ją wyświetlić, przeciągając w dół (przewijając w górę). Ten wzorzec jest powszechnie używany w aplikacjach mobilnych i internetowych w przypadku pasków wyszukiwania, filtrów i innych elementów sterujących, które powinny być dostępne, ale nie od razu widoczne.

Właściwość CSS scroll-initial-target umożliwia deklaratywne wdrożenie tego wzorca tylko za pomocą CSS. Jeśli ustawisz scroll-initial-target: nearest w głównym elemencie treści, kontener przewijania będzie renderowany z ukrytą treścią przewiniętą poza widok. Wcześniej deweloperzy wykorzystywali w tym celu JavaScript (Element.scrollIntoView()) lub identyfikatory fragmentów adresów URL (#content-id), które mają ograniczenia i są trudne do wdrożenia.

Jak to zrobić?

Aby wdrożyć wzorzec „pociągnij, aby wyświetlić”:

  1. Zapewnij kontener przewijania: element docelowy musi znajdować się w kontenerze przewijania (elemencie z przepełnieniem, który umożliwia przewijanie, np. overflow: auto). Może to być dowolny element nadrzędny, w tym element główny <html>.
  2. Zdefiniuj ukryty element: umieść treść, którą chcesz ukryć (np. pasek wyszukiwania), jako pierwszy element podrzędny w kontenerze przewijania. Ten element zostanie przewinięty poza widok podczas początkowego wczytywania.
  3. Zdefiniuj główną treść: umieść element głównej treści bezpośrednio po ukrytym elemencie. To jest element, który użytkownik powinien zobaczyć jako pierwszy.
  4. Kierowanie na główną treść: zastosuj scroll-initial-target: nearest do głównego elementu treści, aby kontener przewijania renderował się z nim przewiniętym do widoku, ukrywając element nad nim.
  5. Dodaj przewijanie z przyciąganiem: aby ukryty element był zawsze w pełni widoczny lub całkowicie ukryty (a nie częściowo przewinięty), dodaj scroll-snap-type: y mandatory do kontenera przewijania oraz scroll-snap-align: start do ukrytego elementu i głównego elementu treści.
/**
 * ANCESTOR: Define the scroll container.
 * Scroll snapping ensures the search bar is always
 * either fully visible or fully hidden.
 */
.scroll-container {
  height: 100vh;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
}

/**
 * HIDDEN ELEMENT: The search bar hidden above the fold on load.
 * It has scroll-snap-align so it snaps into place when pulled down.
 */
.search-bar {
  height: 60px;
  scroll-snap-align: start;
}

/**
 * MAIN CONTENT + TARGET: The element the user sees first.
 * scroll-snap-align makes it a valid snap point.
 * scroll-initial-target tells the browser to scroll here on
 * initial render, hiding the search bar above it.
 */
.main-content {
  scroll-snap-align: start;
  scroll-initial-target: nearest;
}

Strategiczne wdrażanie i sprawdzone metody

  • UŻYWAJ scroll-initial-target: nearest, gdy chcesz zwrócić uwagę użytkownika na konkretną część obszaru przewijania po załadowaniu i celowo ukryć elementy interfejsu, takie jak pasek wyszukiwania na samej górze.
  • NIE należy mylić tego z fokusem ułatwień dostępu. Ta właściwość przesuwa tylko widoczny obszar, a nie fokus klawiatury. Jeśli element docelowy ma być punktem początkowym dla użytkowników klawiatury, musisz ręcznie zarządzać elementem element.focus().
  • NIE używaj tej właściwości, jeśli potrzebujesz płynnej animacji „przewijania” podczas wczytywania. Ta właściwość jest dyskretna i natychmiast ustawia pozycję podczas fazy układu.
  • NIE ustawiaj atrybutu scroll-initial-target na wielu elementach w tym samym kontenerze z możliwością przewijania. Jeśli kilka elementów określa scroll-initial-target: nearest, przeglądarka wybiera ten, który pojawia się jako pierwszy w drzewie DOM.
  • UWZGLĘDNIJ hierarchię pierwszeństwa: fragment adresu URL (np. example.com/#top) i właściwość scroll-start na poziomie kontenera mają pierwszeństwo przed scroll-initial-target.

Strategia zastępcza

W przypadku przeglądarek, które nie obsługują jeszcze interfejsu API, użyj zastępczego kodu JavaScript. Pamiętaj, że w przypadku przeciągania treści w celu ich wyświetlenia główna treść powinna być powiązana z start (górą) kontenera.

/**
 * Progressive Enhancement Fallback
 */
document.addEventListener("DOMContentLoaded", () => {
  // Check for native CSS support
  if (!CSS.supports("scroll-initial-target", "nearest")) {
    const targetContent = document.querySelector('.main-content.target');
    if (targetContent) {
      // Use behavior: "instant" to mimic the native CSS behavior
      // 'block: start' should match your CSS 'scroll-snap-align' (or expected top position)
      targetContent.scrollIntoView({ behavior: 'instant', block: 'start' });
    }
  }
});