Boutons✨ Premium

Icon Slide

Au survol, une flèche apparaît à droite du libellé — opacité 0 → 1 et glissement de 10 px en 300 ms — pendant que les paddings s'échangent (32/24 → 24/32 px) : la largeur du bouton ne bouge pas, le texte se décale de 8 px. CSS seul.

CSSHoverIcon

Mis à jour le

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

3 exemples d'usage

Continuer — étape d'un formulaire en plusieurs pages — Icon Slide exemple 1

① Continuer — étape d'un formulaire en plusieurs pages

QuandFormulaire découpé en étapes : indicateur « 2 sur 4 », deux champs, un bouton de passage à l'étape suivante.
PourquoiLa flèche qui apparaît au survol dit « il y a une suite » au moment où l'utilisateur hésite, sans encombrer le bouton au repos. Le cas d'usage — l'action principale d'un formulaire — était déjà sur l'ancienne fiche.
RéglagesTexte #451a03 (7,0:1), transition: padding .3s sur le bouton, aria-hidden="true" sur la flèche.
Commencer — liste de leçons d'un cours en ligne — Icon Slide exemple 2

② Commencer — liste de leçons d'un cours en ligne

QuandListe de leçons : titre, durée, un petit bouton par ligne.
PourquoiSur une liste d'actions identiques, seule la ligne survolée gagne sa flèche : l'œil suit le curseur et la répétition ne pèse pas. La largeur constante garde les boutons alignés entre les lignes.
Réglagespadding: 8px 14px 8px 18px (survol : 18px / 14px), gap: 6px, font-size: 13px, glyphe ↗ pour les liens qui ouvrent une nouvelle page.
Passer au paiement — récapitulatif de panier — Icon Slide exemple 3

③ Passer au paiement — récapitulatif de panier

QuandEncart de commande : sous-total, livraison, total, un bouton pleine largeur.
PourquoiL'ambre est une couleur d'urgence douce, la flèche annonce l'étape suivante d'un tunnel — le bouton dit ce qui va se passer. Sur toute la largeur, le décalage de 8 px du libellé se voit moins, la flèche davantage.
Réglagesjustify-content: center pour centrer texte et flèche, translateX(-16px) pour une course plus longue, .4s.

Comment ça marche

Le bouton .btn-icon-slide est un conteneur flex (display: flex; align-items: center; gap: 8px) : le texte « Continuer » et le <span class="icon">→</span> sont ses deux enfants, séparés de 8 px. Padding au repos : 16 px en haut et en bas, 32 px à gauche, 24 px à droite (le padding-right: 24px remplace les 32 px de .demo-btn). Fond ambre #f59e0b, texte blanc.

La flèche est opacity: 0 et transform: translateX(-10px), mais elle reste dans le flux : ses 16 px et l'écart de 8 px sont réservés au repos. Mesuré dans Chromium sur le bouton livré (155,5 px) : 32 px à gauche du texte, 24 + 8 + 16 = 48 px à sa droite — le libellé est décalé de 8 px vers la gauche par rapport au centre du bouton, en attendant la flèche invisible.

Au :hover, deux choses : .icon passe à opacity: 1; transform: translateX(0) avec transition: .3s (toutes propriétés, courbe ease), et le bouton échange ses paddings — padding-left: 24px; padding-right: 32px. La somme est inchangée (56 px), donc la largeur aussi (155,5 px avant et après) : aucun décalage des éléments voisins. Mais aucune transition n'est déclarée sur .btn-icon-slide : l'échange est instantané. Mesuré 20 ms après le survol : le libellé a déjà sauté de 8 px vers la gauche (x 224 → 216) alors que la flèche est à 1,5 % d'opacité.

La flèche parcourt ensuite ses 10 px en 300 ms — relativement au texte. À l'écran, sa boîte ayant elle-même reculé de 8 px avec le contenu, elle ne finit qu'à 2 px à droite de sa position invisible de départ (297,8 → 299,8 px) : le « glissement » perçu tient surtout au saut du libellé et au fondu. Une seule déclaration change la sensation : transition: padding .3s sur .btn-icon-slide, et le saut devient un glissement synchronisé avec la flèche, la largeur restant constante à chaque instant puisque les deux paddings s'interpolent symétriquement. À la sortie, la flèche s'efface en reculant de 10 px en 300 ms et les paddings reprennent leurs valeurs d'un coup. Ni :active, ni ombre.

Accessibilité

  • Contraste très insuffisant : texte blanc sur #f59e0b = 2,15:1 — le plus bas des boutons du catalogue, sous le seuil AA de 4,5:1 et même sous 3:1. Gardez l'ambre et passez le texte en sombre : #451a03 (7,0:1) ou #1c1917 (8,1:1) ; si le texte doit rester blanc, assombrissez le fond en #b45309 (5,0:1). La flèche hérite de color : même correction, même gain.
  • La flèche est un vrai caractère (→, U+2192) : les lecteurs d'écran annoncent « Continuer, flèche vers la droite » — et opacity: 0 ne la cache pas aux technologies d'assistance. Posez aria-hidden="true" sur .icon (ou remplacez-la par un SVG avec aria-hidden) : le nom accessible redevient « Continuer ».
  • prefers-reduced-motion absent du code : @media (prefers-reduced-motion: reduce) { .btn-icon-slide .icon { transition: none } } — la flèche apparaît sans glisser. Envisagez aussi de l'afficher en permanence (opacity: 1; transform: none) : une flèche qui n'existe qu'au survol est une information (« il y a une étape suivante ») que les utilisateurs tactiles et clavier ne reçoivent jamais.
  • Clavier : aucun :hover au focus. Doublez les règles avec :focus-visible — .btn-icon-slide:focus-visible .icon { opacity: 1; transform: none } et l'échange de padding — pour que Tab montre la flèche. Tactile : pas de survol, donc jamais de flèche sur téléphone (sauf collée après un tap sur iOS). L'outline natif est conservé.
  • Stabilité : la largeur du bouton est constante au survol (mesurée), rien ne bouge autour de lui — précieux dans une barre de boutons alignés. Cible 51 px de haut (padding 16 px + ligne de 19 px), au-dessus du minimum de 44 px.

Compatibilité navigateur

Requiert display: flex sur un <button> et les transitions sur opacity/transform. Firefox n'a appliqué flex au contenu d'un bouton qu'à partir de la version 52 (2017) : avant, texte et flèche restent alignés mais sans l'écart gap. Aucun JavaScript, zéro dépendance.

Chrome 29+✓ Complet
Firefox 52+✓ Complet
Safari 9+✓ Complet
Edge 12+✓ Complet
Mobile iOS✓ Statique (pas de survol ; flèche collée après un tap)
Android Chrome✓ Statique (pas de survol)

Sans flex, le texte et la flèche restent inline, sans l'écart de 8 px ; sans transitions, la flèche apparaît d'un coup au survol. Dans tous les cas le bouton reste cliquable et lisible.

Le code

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

index.html — structure
<button class="demo-btn btn-icon-slide">
  Continuer
  <span class="icon">→</span>
</button>
Débloquer le code complet — 9,90 € TTC/mois

Le code complet HTML + CSS + JS de Icon Slide, prêt à coller — et les 840 effets. Ou 299 € TTC une fois, accès à vie.

Personnaliser

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

Option / propriétéDéfautEffet
→ (HTML — contenu de .icon) → (U+2192) N'importe quel glyphe ou SVG inline : ↗, ↓ pour un téléchargement, ✓ pour une validation. Un SVG en width: 1em; height: 1em; fill: currentColor hérite de la taille et de la couleur du texte.
translateX(-10px) (CSS — .icon au repos) −10 px Distance parcourue par la flèche. translateX(10px) : elle arrive de la droite ; translateY(6px) : elle monte.
transition: .3s (CSS — .icon) .3s ease Durée du fondu et du glissement. .2s : sec ; .45s cubic-bezier(.2, .8, .2, 1) : arrivée amortie. Ajoutez transition: padding .3s sur .btn-icon-slide pour que le libellé glisse au même rythme au lieu de sauter.
padding 32px / 24px → 24px / 32px (CSS — repos / survol, gauche / droite) 32 / 24 → 24 / 32 L'asymétrie fait les 8 px de décalage du texte. Valeurs égales (28px partout) : plus de décalage, seule la flèche bouge — et la largeur reste constante.
gap: 8px (CSS — .btn-icon-slide) 8 px Espace texte–flèche, réservé même quand la flèche est invisible. 6px resserre ; 12px pour une flèche plus grande.
background: #f59e0b (CSS — .btn-icon-slide) #f59e0b Ambre livré. Pour le contraste AA : texte #451a03 sur cet ambre, ou fond #b45309 sous le texte blanc.
opacity: 0 (CSS — .icon au repos) 0 opacity: .35 laisse deviner la flèche au repos : les utilisateurs tactiles la voient, et l'espace réservé cesse de paraître vide.

FAQ

Parce que l'échange des paddings n'a pas de transition : seul .icon en a une. Ajoutez transition: padding .3s à .btn-icon-slide ; les deux paddings s'interpolent en même temps et la largeur reste constante pendant toute l'animation.
La flèche invisible occupe toujours sa place (16 px + 8 px d'écart) et le padding est asymétrique (32 / 24) : le texte est 8 px à gauche du centre. Trois options : l'assumer (le bouton a un « sens »), afficher la flèche à opacity: .35, ou la sortir du flux (position: absolute; right: 12px) — la largeur devient alors indépendante de la flèche, et le bouton doit garder assez de padding à droite pour l'accueillir.
Mettez le SVG dans le span : <span class="icon" aria-hidden="true"><svg width="1em" height="1em" viewBox="0 0 24 24" fill="currentColor">…</svg></span>. Les règles CSS ciblent .icon et ne changent pas ; currentColor suit la couleur du texte, y compris si vous la corrigez pour le contraste.