Elementy uwzględniające pozycję przewijania

Przegląd

Popraw wygodę korzystania z pływających przycisków, takich jak link „Wróć na górę”, wyświetlając je tylko wtedy, gdy są przydatne. Z tego przewodnika dowiesz się, jak utworzyć te elementy za pomocą CSS container-scroll-state-queries, który umożliwia stylizowanie elementów na podstawie pozycji przewijania ich kontenera bez polegania na detektorach lub obserwatorach przewijania JavaScriptu.

Implementacja

1. Tworzenie kontenera przewijania

Kontener przewijania musi być zadeklarowany jako kontener zapytania o stan przewijania.

.scroller {
  overflow-y: auto;
  /* Establish this element as a scroll-state query container */
  container-type: scroll-state;
}

2. Stylizowanie elementu pływającego

Umieść element w kontenerze i nadaj mu styl. Domyślnie powinien być ukryty.

.back-to-top {
  position: sticky;
  bottom: 20px;
  visibility: hidden;
  opacity: 0;
  translate: 0 20px;
  transition:
    visibility 0.3s,
    opacity 0.3s ease,
    translate 0.3s ease;
}

3. Reagowanie na stan przewijania

Użyj reguły @container z funkcją scroll-state. Aby sprawdzić, czy użytkownik przewinął stronę w dół, sprawdź, czy kontener można przewinąć do góry.

/* When the container can be scrolled toward the top, it means the user has scrolled down */
@container scroll-state(scrollable: top) {
  .back-to-top {
    visibility: visible;
    opacity: 1;
    translate: 0 0;
  }
}

Strategie zastępcze

Podstawowy fallback

Jeśli właściwość container-scroll-state-queries nie jest obsługiwana, element pływający pozostanie niewidoczny z powodu domyślnej wartości visibility: hidden. Aby zapewnić działanie, możesz ustawić element jako zawsze widoczny w nieobsługiwanych przeglądarkach.

/* Fallback for browsers that do not support the feature */
.back-to-top {
  visibility: visible; /* Always visible */
  opacity: 1;
}

/* Override for supported browsers to handle dynamic visibility */
@supports (container-type: scroll-state) {
  .back-to-top {
    visibility: hidden;
    opacity: 0;
  }
  
  @container scroll-state(scrollable: top) {
    .back-to-top {
      visibility: visible;
      opacity: 1;
      translate: 0 0;
    }
  }
}

Zaawansowany fallback (Intersection Observer)

Jeśli wymagana jest dynamiczna widoczność, użyj IntersectionObserver, aby przełączać klasę, gdy element wartowniczy u góry przewijaka znika z widoku.

<!-- Sentinel element placed at the top of the scroller -->
<div class="scroll-sentinel"></div>
/* Marker styling to ensure it does not affect layout */
.scroll-sentinel {
  height: 0;
  width: 0;
  visibility: hidden;
}

.scrolled .back-to-top {
  visibility: visible;
  opacity: 1;
  translate: 0 0;
}
if (!CSS.supports('container-type', 'scroll-state')) {
  const sentinel = document.querySelector('.scroll-sentinel');
  const scroller = document.querySelector('.scroller');

  const observer = new IntersectionObserver((entries) => {
    entries.forEach(entry => {
      // If the sentinel is NOT intersecting, it means the user has scrolled down
      if (!entry.isIntersecting) {
        scroller.classList.add('scrolled');
      } else {
        scroller.classList.remove('scrolled');
      }
    });
  }, { root: scroller });

  observer.observe(sentinel);
}