ITSkillsCenter
Développement Web

Tutoriel : Créer un site one-page avec scroll fluide

5 min de lecture

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

  1. 5 sections : Hero, Services (3 cartes), Portfolio (grille d’images), Tarifs (3 plans), Contact (formulaire)
  2. Navigation fixe avec lien actif au scroll
  3. Animations d’apparition au scroll
  4. Bouton retour en haut
  5. Menu hamburger responsive
  6. Bonus : ajoutez un compteur animé dans la section Hero
#javascript #one-page #scroll
Besoin d'un site web ?

Confiez-nous la Création de Votre Site Web

Site vitrine, e-commerce ou application web — nous transformons votre vision en réalité digitale. Accompagnement personnalisé de A à Z.

À partir de 350.000 FCFA
Parlons de Votre Projet
Publicité

Articles Similaires