WEBLEB
Accueil
Éditeur
Connexion
Pro
Français
English
Français
Español
Português
Deutsch
Italiano
हिंदी
Carrousel de cartes JavaScript
5512
DeveloperUI
Ouvrir dans l'éditeur
Publiez votre code
Recommandé
16 October 2025
Effets d'arrière-plan et de chargement animés CSS
19 May 2025
Éditeur d'images en demi-teintes
25 May 2025
Un code par Liamgilles76
HTML
Copy
Javascript Card Slider Template
1
2
3
4
CSS
Copy
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;700&display=swap'); html, body { margin:0; padding:0; width:100%; height:100%; } body { display:flex; align-items:center; justify-content:center; flex-direction:column; background:#eee; } .cards-wrapper { width:100%; height:300px; max-width:1200px; overflow-x:hidden; position:relative; } .cards { position:absolute; top:15px; left:50%; transform:translateX(-110px); display:flex; flex-direction:row; width:1300px; justify-content:space-between; } .card { width:220px; height:260px; border-radius:14px; border:none; font-family: 'Open Sans', sans-serif; cursor:pointer; box-sizing:border-box; color:#000; } .card h2 { font-size:2.6em; font-weight:300; } .cards-wrapper::after { content:''; display:block; position:absolute; top:0; width:100%; max-width:1200px; height:100%; background:linear-gradient(90deg, #eee 0%, #ffffff00 30%, #ffffff00 70%, #eee 100%); pointer-events:none; } .arrow-btn { width:40px; height:40px; background:#fff; border-radius:50%; border:none; box-shadow: 0 6px 8px #00000030; position:absolute; top:50%; left:20px; transform:translateY(-50%); z-index:1000; cursor:pointer; } .arrow-btn-next { left:auto; right:20px; } .arrow-btn svg { fill:#333; position:absolute; height:80%; left:50%; top:50%; transform:translate(-60%,-50%); } .arrow-btn-next svg { transform:translate(-40%,-50%); }
JS
Copy
const arrowBtns = document.querySelectorAll('.arrow-btn'); const cardBtns = document.querySelectorAll('.card'); let currentCard = 2; let dir = 1; moveCards(); const applyPointerEffect = (btn, ease, shadow) => { btn.onpointerenter = () => gsap.to(btn, { ease, 'box-shadow': shadow }); btn.onpointerleave = () => gsap.to(btn, { ease, 'box-shadow': '0 6px 8px #00000030' }); }; arrowBtns.forEach((btn, i) => { applyPointerEffect(btn, 'expo', '0 3px 4px #00000050'); btn.onclick = () => { dir = (i == 0) ? 1 : -1; currentCard += (i === 0) ? -1 : 1; currentCard = Math.min(4, Math.max(0, currentCard)); moveCards(0.75); }; }); cardBtns.forEach((btn, i) => { applyPointerEffect(btn, 'power3', () => (i === currentCard) ? '0 6px 11px #00000030' : '0 0px 0px #00000030'); btn.onclick = () => { dir = (i < currentCard) ? 1 : -1; currentCard = i; moveCards(0.75); }; }); function moveCards(dur = 0) { gsap.timeline({ defaults: { duration: dur, ease: 'power3', stagger: { each: -0.03 * dir } } }) .to('.card', { x: -270 * currentCard, y: (i) => (i === currentCard) ? 0 : 15, height: (i) => (i === currentCard) ? 270 : 240, ease: 'elastic.out(0.4)' }, 0) .to('.card', { cursor: (i) => (i === currentCard) ? 'default' : 'pointer', 'box-shadow': (i) => (i === currentCard) ? '0 6px 11px #00000030' : '0 0px 0px #00000030', border: (i) => (i === currentCard) ? '2px solid #26a' : '0px solid #fff', background: (i) => (i === currentCard) ? 'radial-gradient(100% 100% at top, #fff 0%, #fff 99%)' : 'radial-gradient(100% 100% at top, #fff 20%, #eee 175%)', ease: 'expo' }, 0) .to('.icon svg', { attr: { stroke: (i) => (i === currentCard) ? 'transparent' : '#36a', fill: (i) => (i === currentCard) ? '#36a' : 'transparent' } }, 0) .to('.arrow-btn-prev, .arrow-btn-next', { autoAlpha: (i) => (i === 0 && currentCard === 0) || (i === 1 && currentCard === 4) ? 0 : 1 }, 0) .to('.card h4', { y: (i) => (i === currentCard) ? 0 : 8, opacity: (i) => (i === currentCard) ? 1 : 0, }, 0); }