navigation · scroll · bouton

Bouton retour en haut

Bouton flottant qui apparaît après un certain scroll et ramène en haut de page en douceur. Nécessite un peu de JavaScript pour détecter le scroll.

Couleurs

Effets

Voir le code source
<style>
.bn-backtotop {
  --bn-totop-bg: #E6E4DD;

  padding: 2rem;
  font-family: 'Inter', sans-serif;
  background: #0B0F10;
  min-height: 140px;
}

.bn-backtotop__hint {
  max-width: 380px;
  color: #979793;
  font-size: 0.85rem;
  line-height: 1.6;
}

.bn-backtotop__btn {
  /* IMPORTANT : "position: fixed" se cale par rapport à la fenêtre
     du VRAI site une fois collé chez toi. Dans cet aperçu (une petite
     iframe), il reste cantonné à la taille de l'aperçu — normal, ce
     n'est qu'une démo, le comportement réel est correct une fois
     copié sur un site. */
  position: fixed;
  right: 24px;
  bottom: 24px;

  width: 46px;
  height: 46px;
  border-radius: 50%;
  border: none;

  background: var(--bn-totop-bg);
  color: #0B0F10;
  font-size: 1.1rem;
  cursor: pointer;

  opacity: 0;
  transform: translateY(10px);
  pointer-events: none;

  transition: opacity 0.25s ease, transform 0.25s ease, box-shadow 0.3s ease;

  --fx-glow: none;
  box-shadow: var(--fx-glow);
}

.bn-backtotop__btn.is-visible {
  opacity: 1;
  transform: translateY(0);
  pointer-events: auto;
}

.bn-backtotop.fx-glow .bn-backtotop__btn {
  --fx-glow: 0 0 30px 4px rgba(230, 228, 221, 0.35);
}

</style>

<div class="bn-backtotop" data-fx-root>
  <p class="bn-backtotop__hint">
    Scrollez cette page (le bloc de code plus bas donne de quoi faire) : le
    bouton apparaît en bas à droite après ~300px de défilement.
  </p>

  <button class="bn-backtotop__btn" type="button" aria-label="Retour en haut">↑</button>
</div>


<script>
/* ==========================================================
   BOUTON RETOUR EN HAUT
   Même principe que le parallax et le fondu au scroll : on
   écoute le scroll de LA VRAIE PAGE qui contient ce composant
   (window.parent si affiché dans une iframe, sinon window
   directement), pour que ça marche pareil en aperçu et sur un
   vrai site.
   ========================================================== */

(function () {
  const root = document.querySelector('.bn-backtotop[data-fx-root]');
  if (!root) return;

  const btn = root.querySelector('.bn-backtotop__btn');
  const isInsideFrame = Boolean(window.frameElement);
  const scrollTarget = isInsideFrame ? window.parent : window;

  function currentScrollY() {
    return isInsideFrame ? window.parent.scrollY : window.scrollY;
  }

  function updateVisibility() {
    // Le bouton apparaît après 300px de scroll
    btn.classList.toggle('is-visible', currentScrollY() > 300);
  }

  btn.addEventListener('click', () => {
    scrollTarget.scrollTo({ top: 0, behavior: 'smooth' });
  });

  scrollTarget.addEventListener('scroll', updateVisibility, { passive: true });
  updateVisibility();
})();

</script>