Tirer pour afficher

Le modèle d'UI "Tirer pour afficher" consiste à masquer un contenu (comme une barre de recherche ou un contrôle d'actualisation) au-dessus d'une zone de défilement lors du chargement initial. L'utilisateur peut alors tirer vers le bas (faire défiler vers le haut) pour l'afficher. Ce modèle est couramment utilisé dans les applications mobiles et Web pour les barres de recherche, les filtres et d'autres commandes secondaires qui doivent être accessibles, mais pas immédiatement visibles.

La propriété CSS scroll-initial-target offre un moyen déclaratif, uniquement en CSS, d'implémenter ce modèle. En définissant scroll-initial-target: nearest sur l'élément de contenu principal, le conteneur de défilement s'affiche avec le contenu masqué hors de l'écran. Auparavant, les développeurs s'appuyaient sur JavaScript (Element.scrollIntoView()) ou sur des identifiants de fragment d'URL (#content-id) pour y parvenir, mais ces deux méthodes présentent des limites et sont difficiles à implémenter.

Implémentation

Pour implémenter un modèle de type "tirer pour afficher" :

  1. Assurez-vous d'avoir un conteneur de défilement : l'élément cible doit se trouver dans un conteneur de défilement (un élément avec un dépassement qui permet le défilement, comme overflow: auto). Il peut s'agir de n'importe quel élément ancêtre, y compris l'élément racine <html>.
  2. Définissez l'élément masqué : placez le contenu que vous souhaitez masquer (par exemple, une barre de recherche) en tant que premier descendant dans le conteneur de défilement. Cet élément sera masqué lors du chargement initial.
  3. Définissez le contenu principal : placez l'élément de contenu principal immédiatement après l'élément masqué. Il s'agit de l'élément que l'utilisateur doit voir en premier.
  4. Cibler le contenu principal : appliquez scroll-initial-target: nearest à l'élément de contenu principal pour que le conteneur de défilement s'affiche avec l'élément de contenu principal visible, en masquant l'élément au-dessus.
  5. Ajouter un défilement scroll-snap : pour vous assurer que l'élément masqué est toujours entièrement visible ou entièrement masqué (et qu'il ne reste pas dans un état de défilement partiel), ajoutez scroll-snap-type: y mandatory au conteneur de défilement, et scroll-snap-align: start à l'élément masqué et à l'élément de contenu principal.
/**
 * 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;
}

Implémentation stratégique et bonnes pratiques

  • À FAIRE : Utilisez scroll-initial-target: nearest lorsque vous souhaitez attirer l'attention de l'utilisateur sur une partie spécifique d'une zone de défilement lors du chargement et masquer intentionnellement les éléments d'interface utilisateur périphériques, comme une barre de recherche tout en haut.
  • NE CONFONDEZ PAS ce concept avec le focus d'accessibilité. Cette propriété ne déplace que la fenêtre d'affichage visuelle. Elle ne déplace pas le focus clavier. Vous devez gérer manuellement element.focus() si la cible est destinée à être le point de départ des utilisateurs du clavier.
  • N'UTILISEZ PAS cette propriété si vous avez besoin d'une animation de défilement fluide lors du chargement. Cette propriété est discrète et définit la position instantanément pendant la phase de mise en page.
  • NE DÉFINISSEZ PAS scroll-initial-target sur plusieurs éléments d'un même conteneur déroulant. Si plusieurs éléments spécifient scroll-initial-target: nearest, le navigateur sélectionne celui qui apparaît en premier dans l'ordre de l'arborescence DOM.
  • À FAIRE : Tenez compte de la hiérarchie de priorité. Un fragment d'URL (par exemple, example.com/#top) et la propriété scroll-start au niveau du conteneur sont tous deux prioritaires sur scroll-initial-target.

Stratégie de remplacement

Pour les navigateurs qui ne sont pas encore compatibles avec l'API, utilisez une solution de remplacement JavaScript. Notez que pour tirer le contenu afin de le révéler, vous devez lier le contenu principal à la partie supérieure (start) du conteneur.

/**
 * 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' });
    }
  }
});