Nouvelle formation Notion en ligne !
Nouvelle formation Notion en ligne !
En profiter
Script
Webflow

Slider avant/après

Javascript
HTML
CSS
Auteur
Aurélien Gallier
Démo lecture seule
Voir
Remix Link
Voir
Démo live
Voir

Copie-colle ce script dans le <body> de ton site Webflow

Ajoute ce script sur ton site Webflow pour rendre fonctionnel ton slider avant/après


<script>
document.addEventListener('DOMContentLoaded', function() {
  document.querySelectorAll('.before-after').forEach(container => {
    const beforeImg = container.querySelector('.before');
    const afterImg = container.querySelector('.after');
    
    if (!beforeImg || !afterImg) return;
    
    // S'assurer que le conteneur a la bonne position
    if (getComputedStyle(container).position === 'static') {
      container.style.position = 'relative';
    }
    
    // Créer le divider
    const divider = document.createElement('div');
    divider.className = 'slider-divider';
    divider.innerHTML = `
      <div class="slider-line" style="
        position: absolute;
        top: 0;
        left: 50%;
        transform: translateX(-50%);
        width: 2px;
        height: 100%;
        background: white;
        z-index: 10;
        box-shadow: 0 0 10px rgba(0,0,0,0.3);
        pointer-events: none;
      "></div>
      <div class="slider-handle" style="
        position: absolute;
        top: 50%;
        left: 50%;
        transform: translate(-50%, -50%);
        width: 40px;
        height: 40px;
        background: white;
        border-radius: 50%;
        display: flex;
        align-items: center;
        justify-content: center;
        box-shadow: 0 2px 10px rgba(0,0,0,0.2);
        z-index: 11;
        cursor: grab;
        transition: transform 0.2s ease;
        pointer-events: all;
      ">
        <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
          <path d="m9 7-5 5 5 5"/>
          <path d="m15 7 5 5-5 5"/>
        </svg>
      </div>
    `;
    
    divider.style.cssText = `
      position: absolute;
      top: 0;
      left: 50%;
      transform: translateX(-50%);
      height: 100%;
      z-index: 10;
      pointer-events: none;
    `;
    
    container.appendChild(divider);
    
    const sliderHandle = divider.querySelector('.slider-handle');
    
    // Variables
    let isDragging = false;
    
    // Fonction de mise à jour
    function updateSlider(percentage) {
      const clampedPercentage = Math.max(0, Math.min(100, percentage));
      const rightClip = 100 - clampedPercentage;
      
      beforeImg.style.clipPath = `inset(0 ${rightClip}% 0 0)`;
      divider.style.left = clampedPercentage + '%';
    }
    
    // Fonction pour obtenir la position X
    function getPositionX(e) {
      return e.type.includes('touch') ? e.touches[0].clientX : e.clientX;
    }
    
    // Fonction pour calculer le pourcentage
    function calculatePercentage(clientX) {
      const rect = container.getBoundingClientRect();
      const x = clientX - rect.left;
      return (x / rect.width) * 100;
    }
    
    // Events pour le drag
    function handleStart(e) {
      if (!sliderHandle.contains(e.target)) return;
      
      e.preventDefault();
      isDragging = true;
      
      sliderHandle.style.cursor = 'grabbing';
      document.body.style.userSelect = 'none';
      
      beforeImg.style.transition = 'none';
      divider.style.transition = 'none';
    }
    
    function handleMove(e) {
      if (!isDragging) return;
      
      e.preventDefault();
      const clientX = getPositionX(e);
      const percentage = calculatePercentage(clientX);
      updateSlider(percentage);
    }
    
    function handleEnd(e) {
      if (!isDragging) return;
      
      isDragging = false;
      sliderHandle.style.cursor = 'grab';
      document.body.style.userSelect = '';
    }
    
    // Event listeners
    sliderHandle.addEventListener('mousedown', handleStart);
    document.addEventListener('mousemove', handleMove);
    document.addEventListener('mouseup', handleEnd);
    
    // Touch events
    sliderHandle.addEventListener('touchstart', handleStart);
    document.addEventListener('touchmove', handleMove, { passive: false });
    document.addEventListener('touchend', handleEnd);
    
    // Clic sur le conteneur pour positionner
    container.addEventListener('click', (e) => {
      if (isDragging || sliderHandle.contains(e.target)) return;
      
      const percentage = calculatePercentage(e.clientX);
      beforeImg.style.transition = 'clip-path 0.3s ease';
      divider.style.transition = 'left 0.3s ease';
      updateSlider(percentage);
      
      setTimeout(() => {
        beforeImg.style.transition = 'none';
        divider.style.transition = 'none';
      }, 300);
    });
    
    // Hover sur la poignée
    sliderHandle.addEventListener('mouseenter', () => {
      if (!isDragging) {
        sliderHandle.style.transform = 'translate(-50%, -50%) scale(1.1)';
      }
    });
    
    sliderHandle.addEventListener('mouseleave', () => {
      if (!isDragging) {
        sliderHandle.style.transform = 'translate(-50%, -50%) scale(1)';
      }
    });
    
    // Initialiser la position
    updateSlider(50);
  });
});
</script>
  

Tuto vidéo

Construis ton slider avant/après

Structure HTML

Ajoute une "div" avec la classe "before-after", puis à l'intérieur places-y 2 éléments "image" avec les classes "after" et "before" et ajoute les images de ton choix.

Style CSS à appliquer dans Webflow

Pour le style réfères-toi à l'exemple de démonstration ou applique les propriétés ci-dessous.

‍Élément avec la classe "before-after":

  • position: relative  
  • display: block
  • overflow: hidden
  • cursor: grab
  • user-select: none (facultatif) -> À placer dans les "Custom properties"

‍Élément avec la classe "before":

  • display: block
  • position: absolute
  • top: 0
  • left: 0
  • width: 100%
  • height: 29rem (En fonction de la taille des images que tu souhaites)
  • fit: cover
  • pointer-events: none
  • clip-path: inset(0 50% 0 0) -> À placer dans les "Custom properties"

Élément avec la classe "after":

  • display: block
  • width: 100%
  • height: 29rem (En fonction de la taille des images que tu souhaites)

Ajoute un slider interactif sur ton site Webflow avec un effet Avant/Après

Envie d'aller plus loin ?
Je m'inscris

Plus de scripts ?