Skip to content

Exemples pratiques

▶ Résultat
🔍 Détails techniques

Fonctionnalités :

  • Bouton burger animé (→ X au click)
  • Navigation responsive (masquée sur mobile)
  • Animation des items de menu avec délai progressif
  • Accessible au clavier

Points clés :

menuBtn.addEventListener('click', () => {
nav.classList.toggle('open');
menuBtn.classList.toggle('active');
});
.nav-item {
animation: slideIn 0.3s ease forwards;
animation-delay: calc(var(--i) * 0.1s);
}

▶ Résultat
🔍 Détails techniques

Fonctionnalités :

  • Chapitres extensibles avec “Voir plus”
  • FAQ avec questions dépliables
  • Transitions fluides
  • Gestion clavier (Enter/Espace)

Code essentiel :

questions.forEach(q => {
q.addEventListener('click', () => {
const answer = q.nextElementSibling;
answer.classList.toggle('open');
});
});

▶ Résultat
🔍 Voir le code source

Effets disponibles :

  • Lift (levée)
  • Glow (lueur)
  • Ripple (ondulation)
  • Slide (glissement)
  • Bounce (rebond)

Exemple - Effet Lift :

.btn-lift:hover {
transform: translateY(-3px);
box-shadow: 0 6px 20px rgba(0,0,0,0.2);
}

▶ Résultat
🔍 Voir le code source

Effets disponibles :

  • Zoom
  • Tilt (inclinaison)
  • Flip (retournement)
  • Glow (lueur)
  • Slide up (glissement)

Exemple - Zoom :

.card-zoom:hover .card-image {
transform: scale(1.1);
}

document.querySelectorAll('a[href^="#"]').forEach(link => {
link.addEventListener('click', (e) => {
e.preventDefault();
const target = document.querySelector(link.getAttribute('href'));
target.scrollIntoView({ behavior: 'smooth' });
});
});

const backToTop = document.querySelector('.back-to-top');
window.addEventListener('scroll', () => {
if (window.scrollY > 300) {
backToTop.classList.add('visible');
} else {
backToTop.classList.remove('visible');
}
});
backToTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
.back-to-top {
position: fixed;
bottom: 2rem;
right: 2rem;
opacity: 0;
pointer-events: none;
transition: opacity 0.3s;
}
.back-to-top.visible {
opacity: 1;
pointer-events: auto;
}

<div class="spinner"></div>
.spinner {
width: 40px;
height: 40px;
border: 4px solid #f3f3f3;
border-top: 4px solid #667eea;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
to { transform: rotate(360deg); }
}

function showToast(message) {
const toast = document.createElement('div');
toast.className = 'toast';
toast.textContent = message;
document.body.appendChild(toast);
setTimeout(() => toast.classList.add('show'), 100);
setTimeout(() => {
toast.classList.remove('show');
setTimeout(() => toast.remove(), 300);
}, 3000);
}
// Usage
showToast('Chapitre sauvegardé !');
.toast {
position: fixed;
bottom: 2rem;
left: 50%;
transform: translateX(-50%) translateY(100px);
padding: 1rem 2rem;
background: #333;
color: white;
border-radius: 0.5rem;
opacity: 0;
transition: all 0.3s ease;
}
.toast.show {
transform: translateX(-50%) translateY(0);
opacity: 1;
}

const images = document.querySelectorAll('.gallery img');
const lightbox = document.querySelector('.lightbox');
const lightboxImg = lightbox.querySelector('img');
images.forEach(img => {
img.addEventListener('click', () => {
lightboxImg.src = img.src;
lightbox.classList.add('active');
});
});
lightbox.addEventListener('click', (e) => {
if (e.target === lightbox) {
lightbox.classList.remove('active');
}
});
.lightbox {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.9);
align-items: center;
justify-content: center;
}
.lightbox.active {
display: flex;
}
.lightbox img {
max-width: 90%;
max-height: 90%;
}

<div class="tabs">
<button data-tab="1" class="active">Chapitre 1</button>
<button data-tab="2">Chapitre 2</button>
<button data-tab="3">Chapitre 3</button>
</div>
<div data-content="1" class="tab-content active">Contenu 1</div>
<div data-content="2" class="tab-content">Contenu 2</div>
<div data-content="3" class="tab-content">Contenu 3</div>
const tabs = document.querySelectorAll('[data-tab]');
const contents = document.querySelectorAll('[data-content]');
tabs.forEach(tab => {
tab.addEventListener('click', () => {
const target = tab.dataset.tab;
tabs.forEach(t => t.classList.remove('active'));
contents.forEach(c => c.classList.remove('active'));
tab.classList.add('active');
document.querySelector(`[data-content="${target}"]`).classList.add('active');
});
});

.progress {
height: 8px;
background: #f0f0f0;
border-radius: 10px;
overflow: hidden;
}
.progress-bar {
height: 100%;
background: linear-gradient(90deg, #667eea, #764ba2);
width: 0;
transition: width 1s ease;
}
// Animer à 70%
progressBar.style.width = '70%';

<div class="card-flip">
<div class="card-front">Face avant</div>
<div class="card-back">Face arrière</div>
</div>
.card-flip {
perspective: 1000px;
}
.card-flip:hover .card-front {
transform: rotateY(180deg);
}
.card-flip:hover .card-back {
transform: rotateY(0);
}
.card-front,
.card-back {
transition: transform 0.6s;
backface-visibility: hidden;
}
.card-back {
transform: rotateY(-180deg);
}

.skeleton {
background: linear-gradient(
90deg,
#f0f0f0 25%,
#e0e0e0 50%,
#f0f0f0 75%
);
background-size: 200% 100%;
animation: loading 1.5s infinite;
}
@keyframes loading {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}

.badge {
position: relative;
}
.badge::after {
content: '';
position: absolute;
top: 0;
right: 0;
width: 10px;
height: 10px;
background: red;
border-radius: 50%;
animation: pulse 2s infinite;
}
@keyframes pulse {
0%, 100% {
transform: scale(1);
opacity: 1;
}
50% {
transform: scale(1.5);
opacity: 0;
}
}