Le site one-page : idéal pour présenter un service
Un site one-page regroupe tout sur une seule page avec des sections. La navigation par scroll fluide (smooth scroll) guide l’utilisateur d’une section à l’autre. Parfait pour les landing pages, portfolios et présentations de services.
Structure HTML
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MonService - Solution digitale au Sénégal</title>
</head>
<body>
<!-- Navigation fixe -->
<nav id="navbar">
<div class="logo">MonService</div>
<ul>
<li><a href="#accueil">Accueil</a></li>
<li><a href="#services">Services</a></li>
<li><a href="#portfolio">Portfolio</a></li>
<li><a href="#tarifs">Tarifs</a></li>
<li><a href="#contact">Contact</a></li>
</ul>
</nav>
<!-- Sections -->
<section id="accueil" class="section hero">
<h1>Développez votre présence digitale</h1>
<p>Sites web, applications et marketing digital à Dakar</p>
<a href="#contact" class="btn">Demander un devis</a>
</section>
<section id="services" class="section">...</section>
<section id="portfolio" class="section">...</section>
<section id="tarifs" class="section">...</section>
<section id="contact" class="section">...</section>
</body>
</html>
CSS : Navigation fixe et sections plein écran
* { margin: 0; padding: 0; box-sizing: border-box; }
/* Scroll fluide natif CSS */
html { scroll-behavior: smooth; }
/* Navigation fixe */
#navbar {
position: fixed;
top: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 15px 40px;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
box-shadow: 0 2px 20px rgba(0,0,0,0.1);
z-index: 1000;
transition: all 0.3s;
}
/* Navbar qui change au scroll */
#navbar.scrolled {
padding: 10px 40px;
background: rgba(255, 255, 255, 0.98);
}
.logo { font-size: 24px; font-weight: 700; color: #667eea; }
#navbar ul { list-style: none; display: flex; gap: 30px; }
#navbar a {
text-decoration: none;
color: #333;
font-weight: 500;
position: relative;
}
/* Soulignement animé au survol */
#navbar a::after {
content: "";
position: absolute;
bottom: -5px;
left: 0;
width: 0;
height: 2px;
background: #667eea;
transition: width 0.3s;
}
#navbar a:hover::after,
#navbar a.active::after { width: 100%; }
/* Sections plein écran */
.section {
min-height: 100vh;
padding: 100px 40px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.section:nth-child(even) { background: #f8f9fa; }
/* Hero */
.hero {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
text-align: center;
}
.hero h1 { font-size: 48px; margin-bottom: 20px; }
.hero p { font-size: 20px; opacity: 0.9; margin-bottom: 30px; }
.btn {
display: inline-block;
padding: 14px 35px;
background: white;
color: #667eea;
border-radius: 30px;
text-decoration: none;
font-weight: 600;
transition: transform 0.3s;
}
.btn:hover { transform: translateY(-3px); }
JavaScript : Navigation active et effets scroll
// 1. Navbar qui change au scroll
const navbar = document.getElementById('navbar');
window.addEventListener('scroll', () => {
navbar.classList.toggle('scrolled', window.scrollY > 50);
});
// 2. Lien actif selon la section visible
const sections = document.querySelectorAll('.section');
const navLinks = document.querySelectorAll('#navbar a');
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
navLinks.forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === '#' + entry.target.id) {
link.classList.add('active');
}
});
}
});
}, { threshold: 0.5 });
sections.forEach(section => observer.observe(section));
// 3. Animation d'apparition au scroll
const animElements = document.querySelectorAll('.anim-scroll');
const animObserver = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
entry.target.classList.add('visible');
}
});
}, { threshold: 0.1 });
animElements.forEach(el => animObserver.observe(el));
CSS des animations au scroll
/* Éléments cachés par défaut */
.anim-scroll {
opacity: 0;
transform: translateY(30px);
transition: opacity 0.6s ease, transform 0.6s ease;
}
/* Apparition quand visible */
.anim-scroll.visible {
opacity: 1;
transform: translateY(0);
}
/* Décalage pour effet cascade */
.anim-scroll:nth-child(2) { transition-delay: 0.1s; }
.anim-scroll:nth-child(3) { transition-delay: 0.2s; }
.anim-scroll:nth-child(4) { transition-delay: 0.3s; }
Bouton « Retour en haut »
<button id="back-to-top" title="Retour en haut">↑</button>
<style>
#back-to-top {
position: fixed;
bottom: 30px;
right: 30px;
width: 45px;
height: 45px;
border-radius: 50%;
background: #667eea;
color: white;
border: none;
font-size: 20px;
cursor: pointer;
opacity: 0;
transition: opacity 0.3s, transform 0.3s;
transform: translateY(20px);
z-index: 999;
}
#back-to-top.visible {
opacity: 1;
transform: translateY(0);
}
</style>
<script>
const btnTop = document.getElementById('back-to-top');
window.addEventListener('scroll', () => {
btnTop.classList.toggle('visible', window.scrollY > 500);
});
btnTop.addEventListener('click', () => {
window.scrollTo({ top: 0, behavior: 'smooth' });
});
</script>
Menu hamburger responsive
/* Ajouter dans le HTML du navbar */
<button class="hamburger" id="menu-btn">☰</button>
<style>
.hamburger { display: none; background: none; border: none; font-size: 28px; cursor: pointer; }
@media (max-width: 768px) {
.hamburger { display: block; }
#navbar ul {
position: fixed;
top: 60px;
right: -100%;
width: 250px;
height: 100vh;
background: white;
flex-direction: column;
padding: 30px;
transition: right 0.3s;
box-shadow: -5px 0 15px rgba(0,0,0,0.1);
}
#navbar ul.open { right: 0; }
.hero h1 { font-size: 28px; }
}
</style>
<script>
document.getElementById('menu-btn').addEventListener('click', () => {
document.querySelector('#navbar ul').classList.toggle('open');
});
// Fermer le menu au clic sur un lien
navLinks.forEach(link => {
link.addEventListener('click', () => {
document.querySelector('#navbar ul').classList.remove('open');
});
});
</script>
Exercice pratique
🎯 Défi : Créez votre landing page one-page
- 5 sections : Hero, Services (3 cartes), Portfolio (grille d’images), Tarifs (3 plans), Contact (formulaire)
- Navigation fixe avec lien actif au scroll
- Animations d’apparition au scroll
- Bouton retour en haut
- Menu hamburger responsive
- Bonus : ajoutez un compteur animé dans la section Hero