Formulaires✨ Premium

Search Expand

Une pastille ronde avec une loupe qui s'étire en champ de recherche de 280 px au clic ou au Tab, et ne se referme que si elle est restée vide.

CSSFocusTransform

Mis à jour le

Cet effet fait partie d'Effect.Labs — 840 effets vanilla, une partie gratuite, une partie premium. Formulaires comprend 20 effets, dont 2 gratuits. Découvrir la catégorie →

3 exemples d'usage

Loupe de l'en-tête d'un blog de cuisine — Pistelune — Search Expand exemple 1

① Loupe de l'en-tête d'un blog de cuisine — Pistelune

QuandEn haut à droite, à côté des rubriques Recettes, Saisons, Desserts : un clic sur la loupe déplie le champ vers la gauche, par-dessus le menu, et trois recettes s'affichent sous lui dès les premières lettres.
PourquoiL'en-tête n'a pas la place d'un champ permanent de 280 px ; la pastille ne prend que 62 px tant qu'on ne cherche rien, et le menu reste lisible.
RéglagesRacine placée en absolu à droite de l'en-tête avec justify-content: flex-end, pour que l'ouverture se fasse vers la gauche. La scène masque le menu avec :focus-within et :has(.sxp-input:not(:placeholder-shown)). aria-label="Search for a recipe".
Filtre de la colonne de contacts d'une messagerie — Caldrune — Search Expand exemple 2

② Filtre de la colonne de contacts d'une messagerie — Caldrune

QuandLa touche « / » donne le focus au filtre depuis n'importe où ; la pastille s'étire sur toute la colonne et la liste ne garde que les contacts dont le nom contient les lettres tapées.
PourquoiUne colonne de 236 px n'a pas la place d'un titre, d'un champ et d'une liste ; la pastille repliée laisse la liste commencer plus haut et s'ouvre au moment de filtrer.
Réglages--sxp-width: 208px, aria-keyshortcuts="/", name="contact". Le raccourci et le tri de la liste sont du code de la scène, branché sur l'événement input.
Bouton « + » d'une liste de courses partagée sur mobile — Panimbre — Search Expand exemple 3

③ Bouton « + » d'une liste de courses partagée sur mobile — Panimbre

QuandSous la liste, une pastille marquée d'un « + » : un toucher la déplie en champ « Ajouter un article », Entrée ajoute la ligne et vide le champ, qui reste ouvert pour l'article suivant ; on le quitte vide, il redevient pastille.
PourquoiSur un écran de téléphone, la pastille ne vole pas de place à la liste, et la règle « fermé seulement si vide » colle à un champ d'ajout : rien ne disparaît tant que l'article n'est pas validé.
RéglagesLoupe remplacée par un SVG « + » dans .sxp-icon, --sxp-width: 226px, aria-label="Ajouter un article", enterkeyhint="done", autocomplete="off".

Comment ça marche

Le champ .sxp-input (type="search") est la pastille elle-même : width: 50px, coins à 50px, et un retrait gauche de 44 px qui laisse la place à la loupe. Avec ce retrait, la pastille fermée mesure en réalité 62 px de large. La loupe .sxp-icon est un SVG posé en absolu par-dessus, à 14 px du bord, transparent aux clics (pointer-events: none) : cliquer dessus revient à cliquer dans le champ.

Deux états ouvrent la pastille : .sxp-input:focus, et .sxp-input:not(:placeholder-shown), c'est-à-dire « le champ contient du texte ». Dans les deux cas la largeur passe à --sxp-width (280 px par défaut), le cadre devient indigo #6366f1 et le fond se teinte légèrement, en 0,5 s avec la courbe cubic-bezier(.4, 0, .2, 1). La loupe passe du gris #8b8b93 à l'indigo tant que le champ a le focus.

Quand la personne quitte le champ, seule la règle du texte peut le garder ouvert : vide, il redevient pastille ; rempli, il reste déplié et montre ce qui a été tapé. Aucune ligne de JavaScript n'est nécessaire, chaque copie de la page se comporte indépendamment. La racine .fx-0287-root n'est qu'un fond de démonstration de 300 px.

Accessibilité

  • Nom du champ : sans libellé visible (la loupe en tient lieu), le champ porte aria-label="Rechercher" ; les lecteurs d'écran annoncent « Rechercher, zone de recherche ». La loupe est masquée avec aria-hidden="true".
  • Envoi : name="q" est fourni. Placé dans un <form role="search">, Entrée envoie la requête ; sur mobile, type="search" affiche la touche Rechercher du clavier.
  • Clavier et toucher : la pastille est le champ lui-même, donc Tab l'ouvre et un toucher aussi, sans élément intermédiaire.
  • Mouvement réduit : sous prefers-reduced-motion: reduce, la pastille s'ouvre et se ferme sans transition.
  • Cible tactile : fermée, la pastille fait environ 62 × 50 px, au-dessus des 44 px recommandés.

Compatibilité navigateur

Repose sur :placeholder-shown (Chrome 47, Firefox 51, Safari 9), une variable CSS (Chrome 49, Firefox 31, Safari 9.1) et appearance: none, déclaré aussi avec le préfixe -webkit- pour effacer le style natif des champs de recherche de Safari. Mesuré dans Chromium, Firefox et WebKit : deux pastilles dans un même formulaire, la seconde ouverte et remplie pendant que la première reste fermée, Tab, toucher, mouvement réduit. Les captures sont jouées par le script des scènes (focus, frappe, raccourci « / » simulés), qui ne fait pas partie du code vendu.

Chrome 49+✓ Complet (mesuré)
Firefox 51+✓ Complet (mesuré)
Safari 9.1+✓ Complet (moteur WebKit mesuré)
Edge 79+✓ Complet (moteur Chromium)
Mobile iOS 9.3+✓ Complet
Android Chrome 49+✓ Complet (moteur Chromium)

Sans :placeholder-shown, la pastille se referme même remplie et cache le texte ; elle s'ouvre toujours au focus. Sans appearance: none, un vieux Safari peut garder les coins et le retrait de son champ de recherche natif.

Le code

Structure HTML à coller dans votre page (le CSS + JS sont inclus avec votre achat) :

index.html — structure
<div class="fx-0287-root">
  <div class="sxp-group">
    <input class="sxp-input" type="search" name="q" aria-label="Rechercher" placeholder="Rechercher...">
    <span class="sxp-icon" aria-hidden="true">
      <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" focusable="false">
        <circle cx="11" cy="11" r="8"></circle>
        <path d="M21 21l-4.35-4.35"></path>
      </svg>
    </span>
  </div>
</div>

Paiement unique, sans abonnement — le code est à toi pour toujours

Personnaliser

Options passées à l'API ou attributs data-* :

Option / propriétéDéfautEffet
Largeur ouverte (CSS — --sxp-width) 280 px Une longueur fixe (px, rem). Pour un pourcentage, donnez d'abord une largeur à .sxp-group, sinon la pastille n'a pas de référence. max-width: 100% empêche de déborder sur mobile.
Sens d'ouverture (CSS — conteneur parent) centré dans la racine Dans un en-tête, alignez le parent à droite (justify-content: flex-end) pour que le champ grandisse vers la gauche, ou à gauche pour qu'il pousse vers la droite.
Durée d'ouverture (CSS — transition de .sxp-input) 0,5 s La couleur de la loupe change, elle, en 0,3 s. Au-dessus de 0,6 s, les premières lettres tapées arrivent avant la fin de l'ouverture.
Couleurs (CSS — border-color, background, color) indigo #6366f1, loupe #8b8b93 Valeurs écrites dans les règles :focus et .sxp-icon ; sur fond clair, passez aussi le texte du champ en sombre.
Icône (HTML — contenu de .sxp-icon) loupe SVG 20 × 20 N'importe quel SVG de 20 px, par exemple un « + » pour un champ d'ajout. Gardez aria-hidden="true" et mettez à jour aria-label.
Texte d'aide (HTML — placeholder) Rechercher... Obligatoire : c'est lui qui permet de savoir si le champ est vide. Pour ne rien afficher, mettez une simple espace.

FAQ

Parce qu'il contient du texte. La pastille ne se referme que vide, pour que la recherche tapée reste visible. Videz le champ (ou appelez input.value = '') et elle se repliera à la sortie suivante.
Entourez le groupe d'un <form role="search" action="/recherche"> : Entrée envoie ?q=… sans bouton supplémentaire, le champ s'appelant déjà q.
Le sélecteur :placeholder-shown sait déjà si le champ est vide, pour chaque champ séparément et sans id. Plusieurs recherches dans la même page s'ouvrent et se ferment donc chacune de leur côté, et l'effet marche même si les scripts sont bloqués.