Ressources pour développeur web

Théme de la semaine : WebDesign

Barre de recherche extensible CSS : Tutoriel + Code complet

Temps de lecture estimé : 8 minutes
Accueil CSS3 Barre de recherche extensible CSS : Tutoriel + Code complet

Coder une barre de recherche extensible moderne et élégante en CSS et JS pour améliorer l’expérience utilisateur tout en optimisant votre design. Dans ce tutoriel, vous allez apprendre à concevoir une barre de recherche interactive en HTML, CSS et JavaScript, simple à intégrer et parfaitement adaptée aux sites actuels.

  • Coder une barre de recherche moderne et élégante qui valorise immédiatement le design de votre site
  • Apprendre à rendre un composant interactif et fluide pour améliorer l’expérience utilisateur sans complexité technique
  • Savoir intégrer facilement une barre de recherche professionnelle dans vos projets web, même en étant débutant

Vous avez sûrement déjà vu ces barres de recherche élégantes qui commencent par une simple icône loupe… puis s’étendent en un champ fluide dès qu’on clique dessus. Nous allons apprendre à construire une barre de recherche extensible avec du HTML, du CSS et un peu de JavaScript. Et surtout, vous allez comprendre chaque ligne, même si vous débutez. On va créer quelque chose de vraiment propre.

Pourquoi utiliser une barre de recherche extensible ?

Avant de coder, comprenons rapidement l’intérêt.

Une barre de recherche classique prend de la place. Sur un design moderne (portfolio, blog, SaaS…), chaque pixel compte.

La barre de recherche extensible, elle :

  • économise de l’espace
  • améliore l’expérience utilisateur
  • donne un effet “premium” immédiat
Barre de recherche extensible

C’est typiquement le genre de détail qui fait dire :

“Ce site est propre.”

Voila ce que nous allons coder :

Étape 1 : la structure HTML

On commence simple. Le HTML sert à poser les fondations.

<div class="search-wrapper" id="searchWrapper">
  <div class="search-box">

    <button class="search-btn" id="searchBtn">
      🔍
    </button>

    <input
      type="text"
      class="search-input"
      id="searchInput"
      placeholder="Rechercher..."
    />

  </div>
</div>
  • search-wrapper : le conteneur principal (il va s’agrandir)
  • search-box : la boîte visuelle (fond, bordures…)
  • search-btn : le bouton loupe
  • search-input : le champ de saisie
  • Retenez bien : on sépare toujours la structure (HTML) du style (CSS).

Étape 2 : donner une forme à la barre

Maintenant, on va transformer ce HTML en vraie barre de recherche stylisée.

.search-wrapper {
  width: 70px;
  height: 70px;
  transition: width 0.4s ease;
}

.search-wrapper.active {
  width: 350px;
}
  • Par défaut → petit carré (juste la loupe)
  • Quand .active est ajouté → la barre s’étend

C’est LA base de votre barre de recherche extensible.

Étape 3 : styliser la boîte

On ajoute un design moderne : effet “glassmorphism”.

.search-box {
  width: 100%;
  height: 100%;
  border-radius: 50px;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,0.2);
  position: relative;
}
  • border-radius: 50px → effet pilule (très moderne)
  • backdrop-filter: blur → effet verre
  • transparence → design léger

Vous venez déjà de créer une barre de recherche moderne.

Étape 4 : positionner la loupe

.search-btn {
  position: absolute;
  left: 5px;
  top: 50%;
  transform: translateY(-50%);
  width: 60px;
  height: 60px;
  border-radius: 50%;
  border: none;
  cursor: pointer;
}

On place la loupe :

  • à gauche
  • parfaitement centrée verticalement

C’est ce qui donne cet effet “propre” qu’on retrouve partout.

Étape 5 : cacher le champ au départ

.search-input {
  width: 100%;
  height: 100%;
  padding-left: 80px;
  border: none;
  outline: none;
  background: transparent;
  color: white;
  opacity: 0;
  transition: opacity 0.3s ease;
}

Puis :

.search-wrapper.active .search-input {
  opacity: 1;
}
  • Au départ → champ invisible
  • Quand actif → il apparaît

Petit détail mais gros impact visuel.

Étape 6 : ajouter l’interaction en JavaScript

Sans JavaScript… rien ne bougera.

const wrapper = document.getElementById("searchWrapper");
const btn = document.getElementById("searchBtn");

btn.addEventListener("click", () => {
  wrapper.classList.toggle("active");
});

Quand vous cliquez sur la loupe :

  • si fermé → ça s’ouvre
  • si ouvert → ça se ferme

Votre barre de recherche interactive est maintenant fonctionnelle.

Étape 7 : améliorer l’expérience utilisateur

On va rendre ça un peu plus intelligent.

Fermer si on clique ailleurs

document.addEventListener("click", (e) => {
  if (!wrapper.contains(e.target)) {
    wrapper.classList.remove("active");
  }
});

Résultat :

  • vous cliquez ailleurs → la barre se referme

Focus automatique

btn.addEventListener("click", () => {
  wrapper.classList.add("active");
  setTimeout(() => {
    document.getElementById("searchInput").focus();
  }, 200);
});

Résultat :

Formation web et informatique - Alban Guillier - Formateur

Des formations informatique pour tous !

Débutant ou curieux ? Apprenez le développement web, le référencement, le webmarketing, la bureautique, à maîtriser vos appareils Apple et bien plus encore…

Formateur indépendant, professionnel du web depuis 2006, je vous accompagne pas à pas et en cours particulier, que vous soyez débutant ou que vous souhaitiez progresser. En visio, à votre rythme, et toujours avec pédagogie.

Découvrez mes formations Qui suis-je ?
  • vous cliquez → vous pouvez directement taper

C’est un détail… mais c’est ce qui fait la différence entre un site “ok” et un site “pro”.

Exemple concret : intégrer une vraie recherche

Pour l’instant, votre barre de recherche ne fait qu’afficher du texte.

Ajoutons une vraie action :

const input = document.getElementById("searchInput");

input.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    alert("Recherche : " + input.value);
  }
});

Ici :

  • vous tapez un mot
  • vous appuyez sur Entrée
  • une action se déclenche

Dans un vrai site, vous redirigeriez vers :

window.location.href = "/search?q=" + input.value;

Astuce design : rendre votre barre encore plus premium

Vous pouvez améliorer votre barre de recherche extensible avec quelques touches simples.

Effet hover

.search-box:hover {
  background: rgba(255,255,255,0.15);
}

Animation plus fluide

transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1);

Ça donne un effet beaucoup plus “haut de gamme”.

Placeholder plus subtil

.search-input::placeholder {
  color: rgba(255,255,255,0.5);
}

Intégrer sur votre site

Imaginons votre site :

  • un blog
  • un portfolio
  • un site e-commerce

Vous pouvez placer cette barre de recherche :

  • dans le header
  • dans une navbar
  • dans un menu flottant

Par exemple :

<header>
  <nav>
    <h1>Mon site</h1>
    <!-- barre ici -->
  </nav>
</header>

Les erreurs à éviter

Quand on débute, on tombe souvent dans ces pièges :

1. Oublier le position: relative

Sans ça, vos éléments vont se placer n’importe où.

👉 En savoir plus sur le positionnement en CSS.

2. Ne pas gérer le clic extérieur

Résultat :

  • la barre reste ouverte
  • UX moyenne

3. Trop d’effets

Attention :

  • trop d’animations = effet “cheap”

Restez sobre. Toujours.

Le code complet pour une barre de recherche extensible

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Barre de recherche extensible</title>

  <style>
    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      min-height: 100vh;
      display: flex;
      align-items: center;
      justify-content: center;
      background:
        radial-gradient(circle at top left, rgba(255,255,255,0.08), transparent 35%),
        linear-gradient(135deg, #0f1115, #171a21 45%, #111318);
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
      padding: 30px;
    }

    .search-wrapper {
      position: relative;
      width: 72px;
      height: 72px;
      transition: width 0.45s cubic-bezier(0.22, 1, 0.36, 1);
    }

    .search-wrapper.active {
      width: 380px;
    }

    .search-box {
      position: relative;
      width: 100%;
      height: 100%;
      border-radius: 999px;
      background: rgba(255, 255, 255, 0.08);
      backdrop-filter: blur(18px);
      -webkit-backdrop-filter: blur(18px);
      border: 1px solid rgba(255, 255, 255, 0.12);
      box-shadow:
        0 10px 30px rgba(0, 0, 0, 0.28),
        inset 0 1px 0 rgba(255, 255, 255, 0.08);
      overflow: hidden;
      transition:
        background 0.35s ease,
        border-color 0.35s ease,
        box-shadow 0.35s ease;
    }

    .search-wrapper.active .search-box,
    .search-wrapper:hover .search-box {
      background: rgba(255, 255, 255, 0.1);
      border-color: rgba(255, 255, 255, 0.18);
      box-shadow:
        0 14px 40px rgba(0, 0, 0, 0.35),
        0 0 0 1px rgba(255, 255, 255, 0.04) inset;
    }

    .search-btn {
      position: absolute;
      top: 50%;
      left: 8px;
      transform: translateY(-50%);
      width: 56px;
      height: 56px;
      border: none;
      border-radius: 50%;
      display: grid;
      place-items: center;
      cursor: pointer;
      background: linear-gradient(145deg, rgba(255,255,255,0.12), rgba(255,255,255,0.04));
      box-shadow:
        inset 0 1px 1px rgba(255,255,255,0.1),
        0 6px 18px rgba(0,0,0,0.18);
      transition:
        transform 0.25s ease,
        background 0.25s ease,
        box-shadow 0.25s ease;
      z-index: 2;
    }

    .search-btn:hover {
      transform: translateY(-50%) scale(1.04);
      background: linear-gradient(145deg, rgba(255,255,255,0.16), rgba(255,255,255,0.06));
    }

    .search-btn:active {
      transform: translateY(-50%) scale(0.98);
    }

    .search-btn svg {
      width: 22px;
      height: 22px;
      stroke: #ffffff;
      stroke-width: 2;
      fill: none;
      opacity: 0.95;
    }

    .search-input {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      padding: 0 24px 0 82px;
      border: none;
      outline: none;
      background: transparent;
      color: #ffffff;
      font-size: 16px;
      font-weight: 400;
      letter-spacing: 0.2px;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.25s ease 0.12s;
    }

    .search-wrapper.active .search-input {
      opacity: 1;
      pointer-events: auto;
    }

    .search-input::placeholder {
      color: rgba(255, 255, 255, 0.5);
    }

    .search-highlight {
      position: absolute;
      inset: 1px;
      border-radius: 999px;
      pointer-events: none;
      background: linear-gradient(
        120deg,
        rgba(255,255,255,0.12),
        rgba(255,255,255,0.03) 30%,
        rgba(255,255,255,0.02) 70%,
        rgba(255,255,255,0.08)
      );
      mask-image: linear-gradient(to bottom, rgba(0,0,0,1), rgba(0,0,0,0.4));
      -webkit-mask-image: linear-gradient(to bottom, rgba(0,0,0,1), rgba(0,0,0,0.4));
    }

    .search-wrapper.active::after {
      content: "";
      position: absolute;
      inset: -6px;
      border-radius: 999px;
      background: radial-gradient(circle, rgba(255,255,255,0.08), transparent 65%);
      z-index: -1;
      filter: blur(10px);
      opacity: 1;
      animation: pulseGlow 2.4s ease-in-out infinite;
    }

    @keyframes pulseGlow {
      0%, 100% {
        opacity: 0.45;
        transform: scale(1);
      }
      50% {
        opacity: 0.75;
        transform: scale(1.02);
      }
    }

    @media (max-width: 480px) {
      .search-wrapper.active {
        width: 100%;
        max-width: 320px;
      }

      body {
        padding: 20px;
      }
    }
  </style>
</head>
<body>

  <div class="search-wrapper" id="searchWrapper">
    <div class="search-box">
      <div class="search-highlight"></div>

      <button class="search-btn" id="searchBtn" aria-label="Ouvrir la recherche">
        <svg viewBox="0 0 24 24" aria-hidden="true">
          <circle cx="11" cy="11" r="7"></circle>
          <path d="M20 20l-3.5-3.5"></path>
        </svg>
      </button>

      <input
        type="text"
        class="search-input"
        id="searchInput"
        placeholder="Rechercher..."
        aria-label="Champ de recherche"
      />
    </div>
  </div>

  <script>
    const searchWrapper = document.getElementById("searchWrapper");
    const searchBtn = document.getElementById("searchBtn");
    const searchInput = document.getElementById("searchInput");

    searchBtn.addEventListener("click", () => {
      const isActive = searchWrapper.classList.contains("active");

      if (!isActive) {
        searchWrapper.classList.add("active");
        setTimeout(() => searchInput.focus(), 220);
      } else if (searchInput.value.trim() === "") {
        searchWrapper.classList.remove("active");
      } else {
        console.log("Recherche :", searchInput.value);
      }
    });

    document.addEventListener("click", (e) => {
      if (!searchWrapper.contains(e.target) && searchInput.value.trim() === "") {
        searchWrapper.classList.remove("active");
      }
    });

    searchInput.addEventListener("keydown", (e) => {
      if (e.key === "Escape" && searchInput.value.trim() === "") {
        searchWrapper.classList.remove("active");
      }
    });
  </script>

</body>
</html>

Aller plus loin

Si vous voulez pousser votre barre de recherche encore plus loin :

  • ajout d’auto-complétion
  • recherche en temps réel
  • suggestions dynamiques
  • connexion à une base de données
  • Etc…

Mais chaque chose en son temps.


Vous venez de créer bien plus qu’un simple champ de saisie. Vous avez conçu une barre de recherche moderne, élégante et interactive, exactement comme sur les sites professionnels.

Ce genre de composant peut sembler “petit”, mais il change complètement la perception de votre site. C’est typiquement ce qui transforme un projet amateur en interface crédible.

Maintenant, à vous de jouer : testez, modifiez, cassez, recommencez. Et surtout, amusez-vous. Parce qu’au fond, coder, c’est un peu comme bricoler… sauf qu’ici, votre outil, c’est votre cerveau.

Découvrez nos autres démos :