Slider avant / après
Deux images superposées, une poignée qui glisse, et le visiteur compare lui-même. Tu poses le script, tu construis trois éléments, c'est en ligne.
/ ÉTAPE 01
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>/ ÉTAPE 02
Construis ton slider avant/après
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.
- 01Pour le style, réfère-toi à l'exemple de démonstration ou applique les propriétés ci-dessous.

/ OÙ LE COLLER
Dans
Webflow, Paramètres › Custom code
CUSTOM CODE
PARAMÈTRES DU PROJET
Head code
Footer code
Les codes personnalisés ne s'appliquent qu'après publication.
Footer code, jamais Head
Le script doit s'exécuter après le contenu de la page. Dans le Head, il ne trouverait rien à animer.
Une seule fois pour tout le site
Il se pose au niveau du projet, pas page par page. Les blocs le trouvent tout seuls.
Publier pour activer
Tant que le site n'est pas publié, le code personnalisé ne tourne pas, même en aperçu.
/ LES OPTIONS
Tout se pilote par classe
et par attribut.
ATTRIBUT
TYPE
RÔLE
.before-after
classe
Le conteneur du slider : le script cherche ses deux images et sa poignée dedans.
.before
classe
L'image de départ, celle que la poignée dévoile.
.after
classe
L'image d'arrivée, posée par-dessus.
.slider-handle
classe
La poignée que le visiteur fait glisser.
/ DANS LA MÊME FAMILLE
Les autres blocs
d'interaction.
/ PLUS DE SCRIPTS
Continue à équiper
tes projets.
SCRIPTJAVASCRIPTTransition de page slide upUne animation de transition entre tes pages, pour une navigation plus fluide.GRATUIT · 1,0 KO · 1 ÉTAPE
SCRIPTJAVASCRIPT · HTML · CSSPlayer vidéo YouTube optimiséAjoute une vidéo sans détruire ton score PageSpeed Insights.GRATUIT · 4,4 KO · 3 ÉTAPES
SCRIPTHTML · CSSTableau comparatif dans un rich textUn tableau comparatif dynamique injecté dans le corps de tes articles.GRATUIT · 4,5 KO · 3 ÉTAPES











